Để so sánh giá trị giữa các phần tử trong cùng một mảng đối tượng, sử dụng $expr kết hợp $let, $indexOfArray và $arrayElemAt trong aggregation.
Tạo collection:
> db.demo366.insertOne({
"Name" : "Chris",
"details" : [
{ "Id" : "John1", "value" : "test" },
{ "Id" : "John2", "value" : 18 },
{ "Id" : "John3", "value" : 20 }
]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e57ddd92ae06a1609a00ae7") }
Xem dữ liệu:
> db.demo366.find();
{ "_id" : ObjectId("5e57ddd92ae06a1609a00ae7"), "Name" : "Chris", "details" : [ { "Id" : "John1", "value" : "test" }, { "Id" : "John2", "value" : 18 }, { "Id" : "John3", "value" : 20 } ] }
Truy vấn so sánh: tìm tài liệu mà value của John2 < value của John3:
> db.demo366.find({
"$expr":{
"$let":{
"vars":{
"john2":{"$arrayElemAt":["$details",{"$indexOfArray":["$details.Id","John2"]}]},
"john3":{"$arrayElemAt":["$details",{"$indexOfArray":["$details.Id","John3"]}]}
},
"in":{"$lt":["$$john2.value","$$john3.value"]}
}
}
})
Kết quả trả về tài liệu thỏa mãn điều kiện (18 < 20).
Phân tích:
$indexOfArray: Tìm vị trí phần tử có Id="John2" trong mảng details.Id$arrayElemAt: Lấy phần tử tại vị trí đó$let: Gán vào biến để dùng lại$lt: So sánh nhỏ hơn
Cách này cho phép so sánh bất kỳ hai phần tử nào trong mảng dựa trên điều kiện tùy chỉnh.