これは私のオブジェクトです:
{ "_id" : ObjectId("53fdcb6796cb9b9aa86f05b9"), "list" : [ "a", "b" ], "complist" : [ { "a" : "a", "b" : "b" }, { "a" : "c", "b" : "d" } ] }
そして、これが私が達成したいことです。「リスト」に特定の要素が含まれているかどうかを確認し、これらの値に関係なくドキュメントを読み取るときに「complist」のオブジェクトからフィールド「a」のみを取得します。私はフォーラムシステムを構築しています。これは、フォーラムの詳細を返すクエリです。ユーザーがフォーラムのホワイトリストに含まれているかどうかを確認しながら、フォーラム情報を読む必要があります。
検索でクエリを使用できます
db.itens.find({},{list:{$elemMatch:{$in:["a"]}}})
特定の値に一致する最初の要素のみを取得します。このようにして、返された配列が空でないかどうかを確認でき、「リスト」に探している値が含まれているかどうかを確認できます。 「リスト」値で探している値が含まれているドキュメントに関係なく、ドキュメントが必要なので、クエリでは実行できません。ドキュメントが必要であり、「リスト」に特定の値があるかどうかを知っている。
集計では、クエリを使用できます
db.itens.aggregate({$project:{"complist.a":1}})
complistに含まれるオブジェクトのフィールド「a」のみを読み取る。これにより、フォーラムのスレッドの基本情報が取得されます。スレッドのすべての情報は必要ありません。
しかし、クエリを使用しようとすると
db.itens.aggregate({$project:{"complist.b":1,list:{$elemMatch:{$in:["a"]}}}})
両方を試してみると、演算子$ elemMatchが無効であるというエラーが表示されます。
$ elemMatchを合計してここで何か間違っていますか?これを達成するためのより良い方法はありますか?
何らかの理由で、$ elemMatchは集計では機能しません。 Mongo 3.2では、新しい$ filter演算子を使用する必要があります。参照 https://docs.mongodb.org/manual/reference/operator/aggregation/filter/
実際、最も簡単な解決策は、配列を$ unwindし、適切なドキュメントを$ matchすることです。 $ groupと$ Pushを使用して、適切なドキュメントを再度まとめることができます。
この質問 への回答が役立つかもしれません。
db.collection_name.aggregate({
"$match": {
"complist": {
"$elemMatch": {
"a": "a"
}
}
}
});
質問は古いですが、2017年11月の寄稿です。
私は同様の問題を抱えていて、2つの連続したマッチ操作を行うとうまくいきました。以下のコードは私のコード全体のサブセットであり、要素名を変更したため、テストされていません。とにかく、これはあなたを正しい方向に向けるべきです。
db.collection.aggregate([
{
"$match": {
"_id": "ID1"
}
},
{
"$unwind": "$sub_collection"
},
{
"$match": {
"sub_collection.field_I_want_to_match": "value"
}
}
])