MongoDB:聚合框架:在字段之间使用$match

24

我有一个测试集合,其中包含两个文档:

> 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*/

你有一些想法吗?

提前感谢。

最好的问候。


1
看起来你在聚合查询中出现了错误。你希望匹配的字段应该指定为a,而不是$a,即db.test.aggregate([{"$match":{"a":{"$gt":"$b"}}}]) - Quolonel Questions
1
@QuolonelQuestions,这仍然不起作用,MongoDB不会使用字段b的值,它将使用$b作为比较的右侧。可以通过执行db.test.aggregate([{"$match":{"a":{"$eq":"$a"}}}])来测试。将返回零个结果。 - Paul
2
在3.6版本中,您可以在常规查询中使用聚合表达式。例如:db.test.find( {"$expr": {"$gt": ["$a", "$b"]}}),并且可以通过聚合操作使用db.test.aggregate( {"$match":{"$expr": {"$gt": ["$a", "$b"]}}}) - s7vr
2个回答

44

在我没有进行太多测试的情况下,我会说你可以使用$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 安装来进行测试。


请问如何在PHP语言中使用上述的MongoDB查询?我尝试了上述方法但不起作用。请帮忙解决这个问题。 - sankar muniyappa
@shankarmsr 使用新的驱动程序:(new \MongoDB\Client())->db->collection->aggregate([['$project' => ['cmp_value' => ['$cmp' => ['$a', '$b']]]], ['$match' => ['cmp_value' => ['$gt' => 0]]]]) 或类似的东西 - Sammaye
让我检查一下你的答案。希望它能正常工作。 - sankar muniyappa

13

使用$expr操作符。

自3.6版本引入,$expr可以构建查询表达式,用于比较同一文档中的字段。

比较单个文档中的两个字段(示例直接取自MongoDB文档):

考虑一个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 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接