web-dev-qa-db-ja.com

MongoDB:集約フレームワーク:フィールド間の$ match

2つのドキュメントを含むテストコレクションがあります。

> db.test.find().pretty()
{ "_id" : ObjectId("510114b46c1a3a0f6e5dd7aa"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("510114c86c1a3a0f6e5dd7ab"), "a" : 3, "b" : 1 }

集約フレームワークでは、aがbより大きいドキュメントのみを取得したいと思います。 $ gtは、フィールドではなく引数の値のみを取得します。

> db.test.aggregate([{"$match":{"$a":{"$gt":"$b"}}}])
{ "result" : [ ], "ok" : 1 } /* don't work*/

アイデアはありますか?

前もって感謝します

宜しくお願いします

19
hotips

うーん、私の側ではあまりテストをしなくても、これには$cmpを使用できると思います。

http://docs.mongodb.org/manual/reference/aggregation/cmp/#_S_cmp

db.test.aggregate([
    {$project: {
        // All your other fields here
        cmp_value: {$cmp: ['$a', '$b']}
    }},
    {$match: {cmp_value: {$gt: 0}}} 
])

より良い方法があるかもしれませんが、テストするためのMongoDBインストールが近くにありません。

37
Sammaye

$expr演算子を使用します。

バージョン3.6で導入された$exprは、同じドキュメントのフィールドを比較するクエリ式を作成できます。

単一のドキュメントからの2つのフィールドの比較MongoDB Docs から直接取得した例):

次のドキュメントを含むmonthlyBudgetコレクションについて考えてみます。

{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }

次の操作では、$exprを使用して、使用額が予算を超えるドキュメントを検索します。

db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )

この操作により、次の結果が返されます。

{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }
0
Govind Rai