Как я могу запросить значения "falsey" в MongoDB?
Я хочу запросить коллекцию Mongo для документов, в которых конкретное поле либо отсутствует, либо имеет значение, которое в Python будет равно false. Это включает в себя атомные значения null
, 0
, ''
(пустая строка), false
, []
, Тем не менее, массивы, содержащие такие значения (такие как ['foo', '']
или просто ['']
) не ложны и не должны совпадать. Могу ли я сделать это с помощью структурированных запросов Mongo (не прибегая к JavaScript)?
$type
не похоже, чтобы помочь:
> db.foo.insert({bar: ['baz', '', 'qux']});
> db.foo.find({$and: [{bar: ''}, {bar: {$type: 2}}]});
{ "_id" : ObjectId("50599937da5254d6fd731816"), "bar" : [ "baz", "", "qux" ] }
2 ответа
Это должно работать
db.test.find({$or:[{a:{$size:0}},{"a.0":{$exists:true}}]})
Просто убедитесь, что a
поле не имеет объекта внутри с 0
ключ.
например
> db.test.find()
{ "_id": ObjectId("5059ac3ab1cee080a7168fff"), "bar": [ "baz", "", "qux" ] }
{ "_id": ObjectId("5059ac48b1cee080a7169000"), "hello": 1, "bar": false, "world": 34 }
{ "_id": ObjectId("5059ac53b1cee080a7169001"), "hello": 1, "world": 42 }
{ "_id": ObjectId("5059ac60b1cee080a7169002"), "hello": 13, "bar": null, "world": 34 }
{ "_id": ObjectId("5059ac6bb1cee080a7169003"), "hello": 133, "bar": [ ], "world": 334 }
{ "_id": ObjectId("5059b36cb1cee080a7169004"), "hello": 133, "bar": [ "" ], "world": 334 }
{ "_id": ObjectId("5059b3e3b1cee080a7169005"), "hello": 133, "bar": "foo", "world": 334 }
{ "_id": ObjectId("5059b3f8b1cee080a7169006"), "hello": 1333, "bar": "", "world": 334 }
{ "_id": ObjectId("5059b424b1cee080a7169007"), "hello": 1333, "bar": { "0": "foo" }, "world": 334 }
> db.test.find({$or: [{bar: {$size: 0}}, {"bar.0": {$exists: true}}]})
{ "_id": ObjectId("5059ac3ab1cee080a7168fff"), "bar": [ "baz", "", "qux" ] }
{ "_id": ObjectId("5059ac6bb1cee080a7169003"), "hello": 133, "bar": [ ], "world": 334 }
{ "_id": ObjectId("5059b36cb1cee080a7169004"), "hello": 133, "bar": [ "" ], "world": 334 }
{ "_id": ObjectId("5059b424b1cee080a7169007"), "hello": 1333, "bar": { "0": "foo" }, "world": 334 }
Я нашел это: https://jira.mongodb.org/browse/SERVER-1854?page=com.atlassian.jira.plugin.system.issuetabpanels:changehistory-tabpanel со дня назад.
Я могу воспроизвести его на моем MongoDB 2.0.1 (я также немного поиграл, чтобы посмотреть, подхватил ли он его как-то еще):
> db.g.find()
{ "_id" : ObjectId("50599eb65395c82c7a47d124"), "bar" : [ "baz", "", "qux" ] }
{ "_id" : ObjectId("5059a0005395c82c7a47d125"), "a" : 3, "b" : { "a" : 1, "b" : 2 } }
> db.g.find({bar: {$type: 4}});
> db.g.find({a: {$type: 2}});
> db.g.find({a: {$type: 16}});
> db.g.find({bar: {$type: 16}});
> db.g.find({bar: {$type: 2}});
{ "_id" : ObjectId("50599eb65395c82c7a47d124"), "bar" : [ "baz", "", "qux" ] }
> db.g.find({bar: {$type: 3}});
> db.g.find({b: {$type: 3}});
{ "_id" : ObjectId("5059a0005395c82c7a47d125"), "a" : 3, "b" : { "a" : 1, "b" : 2 } }
И когда я использую $type
4 Я не могу получить документ с массивом. Как вы можете видеть $type 3
работает нормально (что может быть связано с: https://jira.mongodb.org/browse/SERVER-1475), но массив не может быть выбран.
Возможно, вы видите ошибку. Если вы подадите JIRA на сайт MongoDBs (jira.mongodb.org), это может помочь решить проблему.
Однако, тем не менее, $type
Оп может не решить вашу проблему. Это может быть лучше сделано с помощью метода на стороне клиента, например, полного сброса поля, если в нем нет элементов, которые позволяют запрашивать существование. Это стандартизирует ваши шаблоны запросов и упрощает интеграцию в целом.
Поэтому моя личная рекомендация - стандартизировать значения "фальси" в одно отдельное значение.
редактировать
Я заметил, что они отметили исходную ошибку как дубликат (поэтому она закрыта), однако я не уверен, как она является дубликатом. Эти массивы воспринимаются не как объекты, а как строки, скорее всего, поскольку $ type действует на каждый элемент в этом поле, а не на само поле (или что-то в этом роде).
Я бы по-прежнему открывал JIRA и подчеркивал, что массив вообще нельзя подобрать.