Python - Mongoengine高级查询列表字段
我有一个列表,里面包含了多个子列表,像这样:
li = [[('A', 'one'), ('A', 'two')], [('B', 'three'), ('B', 'four')]]
我需要查询一个Mongo数据库,找出所有对象,这些对象的列表字段中至少包含每个子列表中的一个项目。比如说,找出那些包含要么是 [('A', 'one')] 或者 [('A', 'two')],并且要么是 [('B', 'three')] 或者 [('B', 'four')] 的项目……
我现在使用的是mongoengine,不过如果有其他方法能完成这个任务,我也可以考虑换用其他工具。目前我做了很多这样的查询,以避免重复的结果:
final = set()
for sublist in li:
query = Obj.objects(list_field__in=sublist)
final &= set(query)
问题是,当处理大量查询结果时,这个过程非常慢(我觉得生成结果集需要很长时间)。有没有办法能加快这个过程?特别是,有没有办法能避免从查询结果中创建集合或列表?
我真的希望能写出类似这样的代码:
query = Obj.objects(list_field__in=li[0] AND list_field__in=li[1] AND ...)
编辑:下面的答案经过进一步测试后不适用,因为mongoengine不允许 Q(field=x) & Q(field=y)
编辑2:这是我想要执行的等效mongoDB查询:
db.obj.find({ "$and": [
{"list_field": {"$in":
[["A", "one"], ["A", "two"]]
}},
{"list_field": {"$in":
[["B", "three"], ["B", "four"]]
}}
]})
我能在mongoengine中做到这一点吗?它不让我用 Q(list_field__in=[('A', 'one'), ('A', 'two')]) | Q(list_field__in=[('B', 'three'), ('B', 'four')])
这样的查询。
1 个回答
5
我觉得你可以试试使用Q类来实现这个功能:
filter = reduce(Q.__and__, map(lambda x: Q(list_field__in=x), li))
Obj.objects(filter)