#python-3.x #mongodb
Вопрос:
У меня есть список, аналогичный этому, с уникальными ключами таблицы, и мне нужно получить все записи таблицы, в которых есть эти pk:
lista_pks = [ {'pers_id': '00002', 'cod': '01'}, {'pers_id': '00003', 'cod': '01'}, {'pers_id': '00014', 'cod': '01'}, {'pers_id': '00015', 'cod': '01'}, {'pers_id': '00017', 'cod': '01'}, {'pers_id': '00018', 'cod': '01'}, {'pers_id': '00019', 'cod': '01'} ] columns = {"_id":0,"pers_id":1,"cod":1, "doc":1} database["collection_2"].find(lista_pks ,columns) Expected: |cod | pers_id | doc| --------------------- |01 | 00002 | DNI| |01 | 00003 | DNI| |01 | 00014 | DNI| |01 | 00015 | DNI| |01 | 00017 | DNI| |01 | 00018 | DNI| |01 | 00019 | DNI|
До сих пор мне приходилось фильтровать только по конкретным значениям, но теперь мне нужно повторить что-то подобное, но я не вижу, как я мог бы это сделать:
where (pers_id = '00000002' and cod = '0001') or (pers_id = '00000003' and cod = '0001') or (pers_id = '00000014' and cod = '0001') or (pers_id = '00000015' and cod = '0001') or (pers_id = '00000017' and cod = '0001') or (pers_id = '00000018' and cod = '0001') or (pers_id = '00000019' and cod = '0001')
Изменить: Я создаю функцию, подобную этой:
or_cond = {} and_cond= list() for dict_i in lista_pks: query_aux = {} query_aux['$and'] = [dict_i ] and_cond.append(query_aux) or_cond['$or'] = and_cond Output: {'$or': [{'$and': [{'pers_id': '00002', 'cod': '01'}]}, {'$and': [{'pers_id': '00003', 'cod': '01'}]}, {'$and': [{'pers_id': '00014', 'cod': '01'}]}, {'$and': [{'pers_id': '00015', 'cod': '01'}]}, {'$and': [{'pers_id': '00017', 'cod': '01'}]}, {'$and': [{'pers_id': '00018', 'cod': '01'}]}, {'$and': [{'pers_id': '00019', 'cod': '01'}]}]}
Это работает, но я не знаю, является ли это решение лучшим
Комментарии:
1. Было бы полезно, если бы вы могли предоставить образец набора данных и ожидаемый результат
Ответ №1:
Если вы используете pymongo
result = collection.aggregate([ { "$match": { "pers_id" : { "$in": ["00000017", "00000016"... ] }, "cod": { "$in": ["0001"] } } } ])
вы также можете использовать find вместо aggregate
Комментарии:
1. Если
cod
всегда одно и то же, это сработает, но если это может быть по-другому, это может привести к возвращению нежелательных записей.
Ответ №2:
Фильтры в MongoDB and
по умолчанию редактируются, поэтому вы можете упростить свой запрос до:
db.mycollection.find({'$or': [{'pers_id': '00002', 'cod': '01'}, {'pers_id': '00003', 'cod': '01'}, {'pers_id': '00014', 'cod': '01'}, { ... lt;etcgt; ...}]})
или еще лучше:
db.mycollection.find({'$or': lista_pks})