如何使用MongoDB查询相对元素

如何使用MongoDB查询相对元素,mongodb,Mongodb,我有这样一份文件: { “谁知道呢”:{ “姓名”:“杰夫”, “电话”:“123-123-1234” }, “其他元素”:{ “姓名”:“杰夫”, “电话”:“321-321-3211” } } 如何查询“name”的任何实例?例如,使用通配符可能看起来像 db.collection.find({“*.name”:“Jeff”}) 或者,如果regex是元素位置的支持,它可能看起来像 db.collection.find({/*\.name/:“Jeff”}) 是否可以使用MongoDB

我有这样一份文件:

{
“谁知道呢”:{
“姓名”:“杰夫”,
“电话”:“123-123-1234”
},
“其他元素”:{
“姓名”:“杰夫”,
“电话”:“321-321-3211”
}
}
如何查询“name”的任何实例?例如,使用通配符可能看起来像

db.collection.find({“*.name”:“Jeff”})
或者,如果regex是元素位置的支持,它可能看起来像

db.collection.find({/*\.name/:“Jeff”})
是否可以使用MongoDB实现这一点

旁注:我不是在寻找这样的解决方案

db.collection.find({
“$or”:[
{“whowknows.name”:“Jeff”},
{“anotherElement.name”:“Jeff”}
] 
})

我需要一个真正的相对路径解决方案,因为我不知道父元素是什么(除非有方法生成每个元素的名称-然后我可以在运行时动态生成
$或
子句)。

如果这些是类似的实例,是什么阻止您将它们放入数组?这将更容易质疑

在它的当前形式中,这看起来就像编写自己的$where条件来解析所有文档结构一样好,不是一个有效的操作

虽然效率很低,我不建议在生产环境中使用它,但以下是您可以查询的最简单的方法之一(具有自己的各种捕获):

db.query.find({$where: function() { x = tojsononeline(this); return x.indexOf('"name" : "Jeff",') >= 0; } })

请注意,这将导致表扫描,如果您有一个前置条件,您可能希望在查询中的where子句之前指定该条件。

关于这一点的一切都非常糟糕,您不可能对“name”值之类的内容进行索引,并且每个属性的“路径”在任何地方都会有所不同。所以这对于查询来说是非常糟糕的

<>我注意到你提到了“嵌套”结构,你仍然可以用类似的建议和一些附加的标签来适应这个问题,但是我想让你考虑一下这个“电话簿”类型的例子:

{
“电话”:[
{
“类型”:“主页”,
“姓名”:“杰夫”,
“电话”:“123-123-1234”
},
{
“类型”:“工作”,
“姓名”:“杰夫”,
“电话”:“123-123-1234”
},
]
}
由于这实际上是数组中的子文档,“name”等字段始终共享相同的路径,因此不仅可以为这些字段编制索引(这对性能有好处),而且查询非常基本:

db.collection({“phones.name”:“Jeff”})
在任何“姓名”条目中查找“Jeff”,这正是您所需要的。如果需要层次结构,则在这些子文档中添加一些字段,以指示可以在后期处理中使用的父/子关系。或者甚至作为一个具体化的路径,可以帮助您的查询

这确实是更好的方法

如果您真的必须保持这种结构,那么至少使用JavaScript执行类似的操作,以便在第一次深度匹配时退出:

db.collection.find(
函数(){
var=false;
var finder=功能(对象、字段、值){
if(对象hasOwnProperty(字段)&&obj[field]==值)
发现=真;
如果(发现)返回true;
用于(obj中的var n){
if(Object.prototype.toString.call(obj[n])==“[Object Object]”){
查找器(对象[n],字段,值);
如果(发现)返回true;
}
}
};
查找者(本“姓名”、“杰夫”);
发现退货;
}
)
那里的格式是运算符的简写符号,这对性能来说是个坏消息,但您的结构没有提供太多其他选择。无论如何,函数应该递归到每个嵌套文档中,直到找到带有“value”的“field”


对于任何生产规模的产品,都要考虑将结构更改为可以快速索引和访问的结构。第一个例子应该给你一个起点。由于您当前的结构限制,依赖任意JavaScript进行查询是个坏消息。

Whowknows和anotherElement是否类似/相同类型的文档?@Peeyus存在相同类型文档和不同文档的实例-所有这些都可以包含“name”的实例。“name”元素可以存在于文档的底层,也可以嵌套在其中的多个层中。抛开所有警告,我认为将对象呈现为字符串,然后在字符串上搜索位置会比性能差的解决方案的性能更差。您可以在代码中足够有效地递归结构,而无需求助于此。但总的来说,真正应该做的是实现一个替代的文档结构,并完全避免JavaScript匹配。