Найдите данные в MongoDB с помощью Python, отфильтровав их по списку словарей

#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})