#mongodb #mongodb-query #pymongo #pymongo-3.x
#mongodb #mongodb-запрос #pymongo #pymongo-3.x
Вопрос:
Я получаю значения a, b от пользователя через HTML-форму и передаю его в приведенный ниже запрос. Мое требование — получить документ на основе значений a amp; b, и в случае, если они пусты, мне нужно получить все данные. Может кто-нибудь помочь мне с запросом, пожалуйста? Что я должен передать вместо search_data [«a»] и search_data [«b»], чтобы получить все документы?
query = user_collection.aggregate([
{
"$project": {
"_id": 0
}
},
{
"$match": {
"a": search_data['a'],
"b": search_data['b'],
}
}
])
Комментарии:
1. Можете ли вы поделиться примером документа и ожидаемым результатом?
2. Вместо этого вы должны передать
{$exists:true}
3. { «_id»: ObjectId(«512bc95fe835e68f199c8686»), «автор»: «дейв», «оценка» : 80, «просмотры» : 100 } { «_id»: ObjectId(«512bc962e835e68f199c8687»), «автор»: «дейв», «оценка»: 85, «просмотры» : 521 } =================== В приведенном выше примере данных пользователь укажет автора и оценку — если какое-либо из двух значений отсутствует, запрос должен вернуть все документы.
Ответ №1:
Если вы выполняете только сопоставление и проект, вам не нужен агрегированный запрос, вы можете использовать гораздо более простую find()
операцию.
Приведенный ниже код примет ваш search_data
dict и, используя понимание dict, создаст a search_filter
, который фильтрует только ключи, в которых есть некоторые данные (например), удаляет поля nulls ( None
) и empty ( ''
). Это более приятное решение, поскольку вы можете добавлять больше полей без необходимости изменять код.
search_filter = {k: v for (k, v) in search_data.items() if not (v is None or v == '')}
query = user_collection.find(search_filter, {'_id': 0})
Полностью проработанный пример:
from pymongo import MongoClient
db = MongoClient()['mydatabase']
user_collection = db.user_collection
def filtered_query(search_data):
search_filter = {k: v for (k, v) in search_data.items() if not (v is None or v == '')}
print(search_filter) # Just to show what it is doing
return user_collection.find(search_filter, {'_id': 0})
# Test it out!
filtered_query({'a': 1, 'b': ''})
filtered_query({'a': None, 'b': 3, 'c': 'x'})
filtered_query({'a': 'x123', 'b': 3, 'c': 'x', 'd': None, 'e': '', 'f': 'f'})
дает:
{'a': 1}
{'b': 3, 'c': 'x'}
{'a': 'x123', 'b': 3, 'c': 'x', 'f': 'f'}