5

我想在 Mongo 集合中查询缺少特定字段或具有在 Python 中评估为 false 的值的文档。这包括原子值null, 0, ''(空字符串), false, []. 但是,包含此类值的数组(例如['foo', '']或 just ['']不是虚假的,并且不能匹配。我可以用 Mongo 的结构化查询(不使用 JavaScript)来做到这一点吗?

$type似乎没有帮助:

> db.foo.insert({bar: ['baz', '', 'qux']});
> db.foo.find({$and: [{bar: ''}, {bar: {$type: 2}}]});
{ "_id" : ObjectId("50599937da5254d6fd731816"), "bar" : [ "baz", "", "qux" ] }
4

2 回答 2

4

这应该工作

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 }
于 2012-09-19T12:04:34.987 回答
1

我发现了这个: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 } }

当我使用$type4 时,我无法获取包含数组的文档。如您所见,$type 3工作正常(可能与:https ://jira.mongodb.org/browse/SERVER-1475 相关)但数组似乎无法被捡起来。

您可能会看到错误。如果您在 MongoDB 网站 (jira.mongodb.org) 上提交 JIRA,它可能有助于解决问题。

但是,该$type操作可能无法解决您的问题。这可能通过客户端方法更好地完成,例如完全取消设置字段,如果它没有您查询存在的方式的元素。这使您的查询模式标准化,并且总体上更容易集成。

因此,我个人的建议是将“虚假”值标准化为一个单一的相关值。

编辑

我注意到他们已将原始错误标记为重复(这就是它被关闭的原因)但是我不确定它是如何重复的。这些数组不是作为对象而是作为字符串被拾取的,很可能是因为 $type 作用于该字段中的每个元素而不是字段本身(或类似的东西)。

我仍然会打开一个 JIRA 并强调根本无法拾取该阵列。

于 2012-09-19T10:50:06.160 回答