web-dev-qa-db-ja.com

集計投影で$ elemMatchを使用するにはどうすればよいですか?

これは私のオブジェクトです:

{ "_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を合計してここで何か間違っていますか?これを達成するためのより良い方法はありますか?

13
Stephen Lynx

何らかの理由で、$ elemMatchは集計では機能しません。 Mongo 3.2では、新しい$ filter演算子を使用する必要があります。参照 https://docs.mongodb.org/manual/reference/operator/aggregation/filter/

9
Graeme Pyle

実際、最も簡単な解決策は、配列を$ unwindし、適切なドキュメントを$ matchすることです。 $ groupと$ Pushを使用して、適切なドキュメントを再度まとめることができます。

6
Graeme Pyle

この質問 への回答が役立つかもしれません。

db.collection_name.aggregate({
    "$match": {
        "complist": {
            "$elemMatch": {
                "a": "a"
            }
        }
    }
});
3

質問は古いですが、2017年11月の寄稿です。

私は同様の問題を抱えていて、2つの連続したマッチ操作を行うとうまくいきました。以下のコードは私のコード全体のサブセットであり、要素名を変更したため、テストされていません。とにかく、これはあなたを正しい方向に向けるべきです。

db.collection.aggregate([
    {
        "$match": {
            "_id": "ID1"
        }
    },
    {
        "$unwind": "$sub_collection"
    },
    {
        "$match": {
            "sub_collection.field_I_want_to_match": "value"
        }
    }
])
1
Paulo Pedroso