まず、並べ替えの例の形式が正しくないことに注意してください。aggregateメソッドは配列を入力として受け取ります。ここで、配列の各要素は、集計パイプラインのステージを指定します。また、 $elemMatch にも注意してください。 演算子は$sortステージの一部として使用できません。
並べ替えの例で実行しようとしていることを実現する1つの方法は、集計フレームワークの $ unwind パイプライン演算子。配列を巻き戻すと、配列要素が1つずつ別々のドキュメントに分離されます。たとえば、次のクエリ
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;
}
}