Reputation: 2631
I have a test collection with two documents :
> db.test.find().pretty()
{ "_id" : ObjectId("510114b46c1a3a0f6e5dd7aa"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("510114c86c1a3a0f6e5dd7ab"), "a" : 3, "b" : 1 }
With aggregation framework, I want to get only the documents where a is greater than b. $gt get only values in argument not fields...
> db.test.aggregate([{"$match":{"$a":{"$gt":"$b"}}}])
{ "result" : [ ], "ok" : 1 } /* don't work*/
Do you have some ideas ?
Thanks in advance
Best regards
Upvotes: 24
Views: 25838
Reputation: 15780
$expr
operator.Introduced in version 3.6, $expr
can build query expressions that compare fields from the same document.
Compare Two Fields from A Single Document (example taken directly from MongoDB Docs):
Consider an monthlyBudget collection with the following documents:
{ "_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 }
The following operation uses $expr
to find documents where the spent amount exceeds the budget:
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
The operation returns the following results:
{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }
Upvotes: 13
Reputation: 43884
Hmm without much testing on my end I will say you can use $cmp
for this:
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}}}
])
There might be a better way but I haven't got a MongoDB installation near me to test.
Upvotes: 44