Как получить все документы с помощью запроса $ match в MongoDB Atlas

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