使用聚合来匹配文档元素

时间:2014-02-25 16:43:45

标签: mongodb aggregation-framework pymongo

我不知道如何制定这个问题,所以我最好通过例子来表示。

假设我有以下格式存储的文档:

{'category': [1, 2, 3, ...],
'delete': [2, ...]}

如何仅使用不需要“删除”的“类别”接收文档?聚合的结果必须是:

{'category': [1, 3]}

我尝试以下列方式进行操作,首先我要解开所有类别

{'$unwind': '$category'},

然后我想使用$ match,仅匹配不在“delete”中的类别,但我收到错误: $ nin需要一个数组

{'$match': {'category': {'$nin': '$delete'}}}

我不明白为什么“$ delete”不是数组?

2 个答案:

答案 0 :(得分:4)

在即将发布的MongoDB 2.6版本中,新的$setDifference聚合框架运算符使这一点变得简单,请参阅下面的示例,使用当前版本候选版本:

$ ./mongo --port 31100
MongoDB shell version: 2.6.0-rc0
connecting to: 127.0.0.1:31100/test
test-rs0:PRIMARY> db.foo.insert({category: [1, 2, 3], delete : [2] })
WriteResult({ "nInserted" : 1 })
test-rs0:PRIMARY> db.foo.aggregate(
...     { $project : { diff : { $setDifference : [ "$category", "$delete" ] } } } )
{ "_id" : ObjectId("530ddc2845cec73af61c81c1"), "diff" : [ 1, 3 ] }
test-rs0:PRIMARY>

MongoDB 2.6-rc0上周发布,因此很快就会提供量产版本。

答案 1 :(得分:2)

所以考虑到条件:

{"$match": {"category": {"$nin": "$delete" } }}

您收到的错误是$ nin的参数类型不是数组。

另请考虑以下

{$match: {"category": { "$nin": ["$delete"] } }}

这不匹配,因为两者都没有:

{"$unwind": "$delete" },
{"$match": {"category": {"$ne": "$delete"}}}

但当然这两种形式都会:

{"$match": {"category": { "$nin": [2] } }}

或:

{"$unwind": "$delete" },
{"$match": {"category": {"$ne": 2 }}}

因此,您可以看到“$ delete”引用以您期望的方式进行扩展。在这些情况下它不会这样做,只在$ project和$ group操作员阶段这样做。

您需要使用最后两种情况中显示的文字。