У меня есть список списков, вот так:
li = [[('A', 'one'), ('A', 'two')], [('B', 'three'), ('B', 'four')]]
И мне нужно запросить базу данных mongo, чтобы получить все объекты, поле списка которых содержит хотя бы ОДИН элемент в каждом подсписке li
. Пример: элементы, содержащие либо [('A', 'one') OR ('A', 'two')] И либо [('B', 'three') OR ('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)
Edit2: Вот эквивалентный запрос 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 ответ
Я думаю, вы можете попробовать это через класс Q :
filter = reduce(Q.__and__, map(lambda x: Q(list_field__in=x), li))
Obj.objects(filter)
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
reduce
, но я помещу ваш более подробный ответ в этот комментарий на случай, если кто-то это предпочтет.filter = Q() for sublist in li: filter = filter & Q(list_field__in=sublist) Obj.objects(filter)
Q(list_field__in=x) & Q(list_field__in=y)
, посколькуlist_field
одинаков в обоихQ
.filter = Q() for subli in li: subfilter = Q() for elem in subli: subfilter = subfilter | Q(list_field=elem) filter = filter & subfilter