Проверка наличия нескольких полей в документе MongoDB



Я пытаюсь запросить коллекцию баз данных, содержащую документы процессов, для тех документов, которые имеют определенные поля. Для простоты представим себе следующую общую схему документа:



{
"timestamp": ISODate("..."),
"result1": "pass",
"result2": "fail"
}


Теперь, когда процесс запущен, новый документ вставляется только с меткой времени. Когда этот процесс достигает определенных стадий, поля result1 и result2 добавляются с течением времени. Однако некоторые процессы не достигают стадий 1 или 2 и поэтому не имеют результата поля.

Я хотел бы запросить базу данных, чтобы получить только те документы, которые имеют как result1, так и result2.



Я знаю об операторе $exist, но, насколько я могу судить, это работает только для одного поля одновременно, т. е. db.coll.find({"result1": {$exists: true}}). Оператор $exists не может использоваться в качестве оператора верхнего уровня. Например, это делает не работу:


db.coll.find({"$exists": {"result1": true, "result2": true}})




Чтобы проверить оба результата, мне понадобится:




db.coll.find({"result1": {"$exists": true}, "result2": {"$exists": true}})




Теперь это уже становится утомительным для более чем одной переменной.



Есть ли лучший способ сделать это?
(Кроме того, я делаю это в Python, так что если есть решение только для драйвера pymongo, которое уже сделало бы меня счастливым.)

663   2  

2 ответов:

Я не знаю, как лучше, но вы всегда можете обрабатывать с помощью JavaScript через $where:

jsStr = """var doc = this;
           return ['result1','result2','result3']
           .every(function(key) { 
               return doc.hasOwnProperty(key) 
           });"""

coll.find({ "$where": jsStr })

Но вам придется указать массив "ключей" для проверки где-то.

Если вы думаете, что у вас есть много ключей для ввода, то почему бы просто не" построить " выражение запроса:

whitelist = [ "result1", "result2", "result3" ]
query = {}

for key in whitelist:
    query[key] = { "$exists": True }

coll.find(query)

Это экономит немного типизации, и поскольку все запросы MongoDB в любом случае являются просто структурами данных, то использование базовой манипуляции данными для построения запросов имеет смысл.

Как насчет использования $and:

db.coll.find({"$and": [                                                                     
            { "fld1": { "$exists": true }}                                              
            , { "fld2": { "$exists": true }}                                            
            , { "fld3": { "$exists": true }}                                            
]})  

Comments

    Ничего не найдено.