如何在任意深度查找MongoDB字段名

如何在任意深度查找MongoDB字段名,mongodb,recursion,mongodb-query,Mongodb,Recursion,Mongodb Query,我将一些松散的XML数据导入到Mongo数据库中。每个文档的嵌套子文档深度约为5-10。我想查找具有特定字段的特定值的()文档,该字段可能出现在子文档的任何深度(并且可能出现多次) 我目前正在将每个文档拉入Python,然后搜索该字典,但是如果我可以声明一个过滤器原型,其中数据库将只返回在其内容中某处具有特定字段名值的文档,那就太好了 以下是一个示例文档: { “福”:1, “酒吧”:2, “找到这个”:“是的!”, “东西”:{ "baz":3,, “狼吞虎咽”:[ “威布尔”, “摆动”,

我将一些松散的XML数据导入到Mongo数据库中。每个文档的嵌套子文档深度约为5-10。我想查找具有特定字段的特定值的()文档,该字段可能出现在子文档的任何深度(并且可能出现多次)

我目前正在将每个文档拉入Python,然后搜索该字典,但是如果我可以声明一个过滤器原型,其中数据库将只返回在其内容中某处具有特定字段名值的文档,那就太好了

以下是一个示例文档:

{
“福”:1,
“酒吧”:2,
“找到这个”:“是的!”,
“东西”:{
"baz":3,,
“狼吞虎咽”:[
“威布尔”,
“摆动”,
{
"一败涂地":四,,
“找到这个”:“请找到我”
}                
],
“plugh”:{
“plove”:{
“找到这个”:“也在这里!”
}
}
}
}

因此,我想查找具有“find this”字段的文档,并且(如果可能)能够查找具有“find this”字段特定值的文档。

您在BSON文档不是XML文档的特定语句中是对的。由于XML被加载到由“节点”组成的树结构中,所以搜索任意键非常容易

MonoDB文档的处理并不是那么简单,在许多方面它都是一个“数据库”,因此通常希望它的数据位置具有一定的“一致性”,以便于“索引”和搜索

尽管如此,这是可以做到的。当然,这意味着在服务器上执行一个递归过程,这意味着使用JavaScript进行处理

作为一个基本的shell示例,但是通用的
函数
只是
$where
操作符的字符串参数:

db.collection.find(
函数(){
var findKey=“找到这个”,
findVal=“请找到我”;
功能检查对象(doc){
返回Object.key(doc).some(函数)(key){
if(typeof(doc[key])=“object”){
返回检查对象(单据[键]);
}否则{
返回(key==findKey&&doc[key]==findVal);
}
});
}
返回检查对象(本);
}
)
因此,基本上,测试对象中的键,看看它们是否匹配所需的“字段名”和内容。如果其中一个键恰好是“对象”,则递归到函数中并再次检查

JavaScript确保找到的“第一个”匹配将从搜索函数返回,给出一个
true
结果,并返回在某个深度上存在该“键/值”的对象

请注意,
$where
本质上意味着遍历整个集合,除非存在可应用于集合上“索引”的其他有效查询筛选器

因此,请谨慎使用,或者干脆不使用,只需将数据重新构造为更可行的形式即可


但这将为您提供匹配项。

以下是一个示例,我使用它递归搜索文档结构中任意位置的键值:

db.getCollection('myCollection').find({

    "$where" : function(){

        var searchKey = 'find-this';
        var searchValue = 'please find me';

        return searchInObj(obj);

        function searchInObj(obj){                            
          for(var k in obj){       
            if(typeof obj[k] == 'object' && obj[k] !== null){
              if(searchInObj(obj[k])){
                return true;
              }
            } else {
              if(k == searchKey && obj[k] == searchValue){
                return true;
              }
            }          
          }                         
          return false;
        }       
    }    
})

该死的服务器端脚本,蝙蝠侠!我不知道你可以在数据库中运行JS!这真的很酷,你的解决方案非常有意义。非常感谢!哦,你知道吗?我打赌您可以使用“或”$where子句执行find():让数据库使用自己的(fast)机制来查找“key to search”和“value to search”,以确定键在顶层的位置,并提供递归搜索JS函数,用于“key to search”不在顶层的所有节点。如果我能让它工作的话,我会把它添加到这个问题上。我知道这是一个旧的答案,但是
obj
return searchInObj(obj)中来自哪里?如文档所述:“使用this或obj在JavaScript表达式或函数中引用文档”