我想搜索MongoDB,以便只获得在密钥元素的某些配置中找到所有x的结果。这是this previous question的延续。
collected = [] # Initialize an empty list
for x in input: # Iterate over input
collected.append(re.compile(x)) # Append re.compile object to list
cursor = db.collection.find({"key": {"$all": collected}})
现在它返回输入列表元素出现在提供的键的任何元素中的所有文档。如何只获得输入列表元素出现在键元素中的结果?
例如
时input = ['A', 'B', 'C', 'D']
它将返回带有
的文档key = ['AHBKCOD', 'NDSI']
但不是
key = ['A', 'B', 'C', 'D', 'AB']
返回匹配元素会很棒'AHBKCOD'也是直接的。
答案 0 :(得分:1)
设置测试数据:
> db.test.insert({'key': ['AHBKCOD', 'NDSI']})
> db.test.insert({'key': ['A', 'B', 'C', 'D', 'AB']})
您当前的查询确实与两个记录都匹配,因此$all
不是我们想要的运算符:
> db.test.find({"key": {"$all": [/A/, /B/, /C/, /D/]}}, {'_id': 0})
{ "key" : [ "AHBKCOD", "NDSI" ] }
{ "key" : [ "A", "B", "C", "D", "AB" ] }
要匹配包含一组正则表达式的字符串并重新构造返回对象,您需要使用aggregation framework。此查询所需的操作包括$unwind
,$match
,$ and
和$project
> db.test.aggregate([{"$unwind": "$key"},
{"$match": {"$and": [{"key": /A/},
{"key": /B/},
{"key": /C/},
{"key": /D/}]}},
{"$project": {"_id": 0, "key": "$key"}}])
这将只返回您想要的密钥:
{ "result" : [ { "key" : "AHBKCOD" } ], "ok" : 1 }
如果您运行的是mongo 2.6或更高版本,那么聚合函数将返回一个游标,就像查询查询一样。 2.6以下,您将获得一个包含顶级密钥的文档,result
和'确定'。要提取结果数组,您可以将["result"]
添加到查询的末尾。
[ { "key" : "AHBKCOD" } ]
将此转换为Python的工作很少,因为JSON (和mongo扩展JSON)可以使用而不会改变太多,因为它们通常是值Python结构(字典,列表) 特别是如果你小心引用键。 Python没有像/A/
那样的正则表达式文字,所以我们需要进行一次更改,转换为re.compile(r'A')
。
input = ['A', 'B', 'C', 'D']
collected = [{"key": re.compile(x)} for x in input]
query = [{"$unwind": "$key"},
{"$match": {"$and": collected}},
{"$project": {"_id": 0, "key": "$key"}}]
result = db.test.aggregate(query)["result"]
我假设您在这里使用的是2.6以下版本的MongoDB。
print result
[{u'key': u'AHBKCOD'}]
对于值列表,您可以使用列表推导:
print [res['key'] for res in result]
[u'AHBKCOD']