MongoDB查询帮助 – 查询子对象中任何键的值
我想对这个集合执行一个查询,以确定哪些文档在匹配某个值的东西中有任何键。 这可能吗?
我有一个文件的集合,如:
{ "things": { "thing1": "red", "thing2": "blue", "thing3": "green" } }
编辑:为了简洁
我build议模式更改,以便您可以在MongoDB中进行合理的查询。
从:
{ "userId": "12347", "settings": { "SettingA": "blue", "SettingB": "blue", "SettingC": "green" } }
至:
{ "userId": "12347", "settings": [ { name: "SettingA", value: "blue" }, { name: "SettingB", value: "blue" }, { name: "SettingC", value: "green" } ] }
然后,你可以索引"settings.value"
,并做一个查询,如:
db.settings.ensureIndex({ "settings.value" : 1}) db.settings.find({ "settings.value" : "blue" })
改变真的很简单,因为它将设置名称和设置值移动到完全可索引字段,并将设置列表作为数组存储。
如果你不能改变模式,你可以试试@JohnnyHK的解决scheme ,但是要注意的是,在性能方面基本上是最坏的情况,并且不能有效地处理索引。
如果你不知道密钥是什么,并且你需要它是交互的,那么你需要使用(出色的性能挑战) $where
操作符(在shell中):
db.test.find({$where: function() { for (var field in this.settings) { if (this.settings[field] == "red") return true; } return false; }})
如果你有一个很大的集合,这可能对你来说太慢了,但如果你的密钥集是未知的,这是你唯一的select。
可悲的是,之前的答案都没有解决mongo可以在数组或嵌套对象中包含嵌套值的事实。
这是正确的查询:
{$where: function() { var deepIterate = function (obj, value) { for (var field in obj) { if (obj[field] == value){ return true; } var found = false; if ( typeof obj[field] === 'object') { found = deepIterate(obj[field], value) if (found) { return true; } } } return false; }; return deepIterate(this, "573c79aef4ef4b9a9523028f") }}
由于在数组或嵌套对象上调用typeof将返回“object”,这意味着查询将对所有嵌套元素进行迭代,并遍历所有嵌套元素,直到find具有值的键为止。
您可以使用嵌套值检查以前的答案,结果将远离期望。
把整个对象串起来会对性能造成很大的影响,因为它必须一个接一个地遍历所有的内存扇区来匹配它们。 并在RAM内存中创build一个对象的副本作为string(既低效,因为查询使用更多的内存和缓慢,因为function上下文已经有一个加载的对象)。
查询本身可以使用objectId,string,int和你想要的任何基本的javascripttypes。