Trước tiên, hãy lưu ý rằng ví dụ sắp xếp của bạn không đúng định dạng:phương thức tổng hợp lấy một mảng làm đầu vào, trong đó mỗi phần tử trong mảng chỉ định một giai đoạn trong một đường ống tổng hợp. Ngoài ra, hãy lưu ý rằng $ elemMatch không thể sử dụng toán tử như một phần của giai đoạn $ sort.
Một cách để đạt được những gì bạn đang cố gắng thực hiện với ví dụ sắp xếp của mình là sử dụng $ thư giãn nhà điều hành đường ống. Việc giải nén một mảng sẽ bóc tách từng phần tử của mảng thành các tài liệu riêng biệt. Ví dụ:truy vấn sau
db.my_collection.aggregate([ {$unwind: "$answers"} ]);
trả về một cái gì đó như sau:
[
{
"_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
"user" : "bruno",
"answers" : {
"id" : 0,
"value" : 3.5
}
},
{
"_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
"user" : "bruno",
"answers" : {
"id" : 1,
"value" : "hello"
}
},
{
"_id" : ObjectId("523715813fac8e36fdb0b96f"),
"user" : "bruno2",
"answers" : {
"id" : 0,
"value" : 0.5
}
},
{
"_id" : ObjectId("523715813fac8e36fdb0b96f"),
"user" : "bruno2",
"answers" : {
"id" : 1,
"value" : "world"
}
}
]
Thêm giai đoạn so khớp $ sẽ cho phép bạn chỉ lấy các tài liệu có answer.id bằng 0. Cuối cùng, giai đoạn $ sort cho phép bạn sắp xếp theo giá trị answer.value. Tất cả cùng một truy vấn tổng hợp là:
db.my_collection.aggregate([
{$unwind: "$answers"},
{$match: {"answers.id": 0}},
{$sort: {"answers.value": -1}}
]);
Và đầu ra:
[
{
"_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
"user" : "bruno",
"answers" : {
"id" : 0,
"value" : 3.5
}
},
{
"_id" : ObjectId("523715813fac8e36fdb0b96f"),
"user" : "bruno2",
"answers" : {
"id" : 0,
"value" : 0.5
}
}
]
Dựa trên những gì bạn yêu cầu, có vẻ như bạn sẽ không cần $ unwind hoặc thậm chí là khung tổng hợp. Thay vào đó, nếu bạn muốn tìm tài liệu có answer.id bằng 0 và answers.value bằng 3,5, sau đó thay đổi answer.value thành 4, bạn có thể sử dụng find với $ elemMatch theo sau là db.collection.save ():
doc = db.my_collection.findOne({"answers": {$elemMatch: {"id": 0, "value": 3.5}}});
for (i=0; i<doc.answers.length; i++) {
if (doc.answers[i].id === 0) {
doc.answers[i].value = 4;
db.my_collection.save(doc);
break;
}
}