4

MongoDB の新しいバージョンでは、$elemMatch 射影演算子を使用して、クエリの応答を配列の単一の一致する要素に制限できます。http://docs.mongodb.org/manual/reference/projection/elemMatch/

しかし、マングース3ではまだ機能していないようです。例を次に示します。

{
 _id: ObjectId(5), 
 items: [1,2,3,45,4,67,9,4]
}

Folder.findOne({_id: Object(5)}, {$elemMatch: {$in: [1,67,9]}})
  .exec(function (err, doc) {

});

次のドキュメントを取得する予定です。

{
 _id: ObjectId(5), 
 items: [1,67,9]
}

しかし残念ながら、私が得ているのはすべてのアイテムを含むドキュメントです:

{
 _id: ObjectId(5), 
 items: [1,2,3,45,4,67,9,4]
}
4

4 に答える 4

4

ここの mongodb ドキュメントは誤解を招く可能性があります。更新します。

つまり、プロジェクション、つまりフィールド選択で $elemMatch を使用できるようになりました。

https://gist.github.com/3640687

参照: https://github.com/learnboost/mongoose/issues/1085

[編集] 送信されたドキュメントのプル リクエスト: https://github.com/mongodb/docs/pull/185

于 2012-09-05T17:35:29.973 に答える
2

まず、items$elemMatch 演算子の前にフィールド名がありません。クエリは次のようになります

Folder.findOne({_id: Object(5)}, {items: {$elemMatch: {$in: [1,67,9]}}})
  .exec(function (err, doc) { });

ただし、ドキュメントに記載されているように、これでも目的の結果は返されません。

$elemMatch プロジェクションは、ソース ドキュメントごとに 1 つの配列要素のみに一致します。

したがって、次のようなものしか返されません。

{
 _id: ObjectId(5), 
 items: [1]
}
于 2012-09-05T05:50:11.427 に答える
1

ノードでこれを行うようにマングースを設定していませんが、2.2の新しい集計フレームワークを使用して必要な結果を取得することもできます-これは、必要な結果を取得する例です。まず、私のサンプルドキュメントは次のようになります。

> db.foo.findOne()
{
    "_id" : ObjectId("50472eb566caf6af6108de02"),
    "items" : [
        1,
        2,
        3,
        45,
        4,
        67,
        9,
        4
    ]
}

あなたが望むものに到達するために、私はこれをしました:

> db.foo.aggregate( 
             {$match : {"_id": ObjectId("50472eb566caf6af6108de02")}},  
             {$unwind : "$items"},  
             {$match : {"items": {$in : [1, 67, 9]}}},  
             {$group : {_id : "$_id", items : { $push : "$items"}}},
             {$project : {_id : 0, items : 1}}
     )
{
    "result" : [
    {
        "_id" : ObjectId("50472eb566caf6af6108de02"),
        "items" : [
            1,
            67,
            9
        ]
    }
],
"ok" : 1

}

説明するために、詳細に私はそれを一行ずつ取り上げます:

{$match : {"_id": ObjectId("50472eb566caf6af6108de02")}}

これはかなり明白です-これは基本的に通常のクエリの検索基準と同等であり、結果は処理されるパイプラインの次のステップに渡されます。インデックスなどが使える一枚です。

{$unwind : "$items"}

これにより、配列が分解され、配列の要素ごとに1つずつドキュメントのストリームが作成されます。

{$match : {"items": {$in : [1, 67, 9]}}}

この2番目の一致では、リスト内のドキュメントのみが返され、基本的にドキュメントのストリームが3つの結果セットに削減されます。

{$group : {_id : "$_id", items : { $push : "$items"}}}

出力を配列にしたいので、グループ化するキーとして_idを使用して、必要なアイテムを選択したので、上記のアンワインドを元に戻す必要があります。注:複数の一致がある場合、これには繰り返し値があります。一意のリストが必要な場合は、$addToSet代わりに使用します$push

{$project : {_id : 1, items : 1}}

最後に、このプロジェクションは実際には必要ありませんが、機能を説明するために含めました。必要に応じて、_idを返さないように選択することもできます。

于 2012-09-05T11:13:33.510 に答える
-1

通常、$elemMatch も MongoDB も、配列からデータをフィルター処理しません。$elemMatch を使用してドキュメントを照合できますが、返されるデータには影響しません。フィルター パラメーター (find() findOne() 呼び出しの 2 番目のパラメーター) を使用して、ドキュメントからフィールドを含める/除外することしかできませんが、一部のクエリ入力に基づいて結果をフィルター処理することはできません。

于 2012-09-05T05:47:13.937 に答える