首先,请注意您的排序示例格式错误:聚合方法将数组作为输入,其中数组中的每个元素指定聚合管道中的一个阶段。另外,请注意$elemMatch运算符不能用作 $sort 阶段的一部分。
实现排序示例的一种方法是使用聚合框架的$unwind管道运算符。展开数组会将数组元素一个接一个地剥离到单独的文档中。例如,以下查询
db.my_collection.aggregate([ {$unwind: "$answers"} ]);
返回如下内容:
[
{
"_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"
}
}
]
添加 $match 阶段将允许您仅获取 answers.id 为零的文档。最后,$sort 阶段允许您按 answers.value 排序。聚合查询一起是:
db.my_collection.aggregate([
{$unwind: "$answers"},
{$match: {"answers.id": 0}},
{$sort: {"answers.value": -1}}
]);
和输出:
[
{
"_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
"user" : "bruno",
"answers" : {
"id" : 0,
"value" : 3.5
}
},
{
"_id" : ObjectId("523715813fac8e36fdb0b96f"),
"user" : "bruno2",
"answers" : {
"id" : 0,
"value" : 0.5
}
}
]
根据您的要求,听起来您并不总是需要 $unwind 甚至聚合框架。相反,如果您想查找 answers.id 等于 0 且 answers.value 等于 3.5 的文档,然后将 answers.value 更改为 4,您可以使用 find 和 $elemMatch,然后是 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;
}
}