I have a list similar to this with the unique keys of a table and I need to retrieve all the records of a table that have these 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|
Until now I only had to filter by concrete values but now I need to replicate something like this but I can't see how I could do it:
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')
Edit: I create a function like this:
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'}]}]}
It works but I don't know if this solution is the best
CodePudding user response:
If you are using pymongo
result = collection.aggregate([
{
"$match": {
"pers_id" : {
"$in": ["00000017", "00000016"... ]
},
"cod": {
"$in": ["0001"]
}
}
}
])
you can also use find instead of aggregate
CodePudding user response:
Filters in MongoDB are and
ed by default, so you can simplify your query to:
db.mycollection.find({'$or': [{'pers_id': '00002', 'cod': '01'},
{'pers_id': '00003', 'cod': '01'},
{'pers_id': '00014', 'cod': '01'},
{ ... <etc> ...}]})
or better still:
db.mycollection.find({'$or': lista_pks})