Проверка наличия нескольких полей в документе 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, которое уже сделало бы меня счастливым.)
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