如何找到在任意深度MongoDB的字段名如何找到在任意深度MongoDB的字段名(How to fi

2019-05-10 14:10发布

我进口了一些草率的XML数据整理成一个数据库蒙戈。 每个文档都有的嵌套的子文件到5-10左右的深度。 我想找到()具有特定领域,其中场可以在任何深度的子文档出现(可能会多次出现)的特定值的文档。

我目前拉动每个文件成Python,然后寻找那本词典,但它会很好,如果我能说出一个过滤器的原型,其中该数据库将只返回具有字段名在其内容的特定值的地方文件。

下面是一个例子文件:

{
    "foo": 1,
    "bar": 2,
    "find-this": "Yes!",
    "stuff": {
        "baz": 3,
        "gobble": [
            "wibble",
            "wobble",
            {
                "all-fall-down": 4,
                "find-this": "please find me"
            }                
        ],
        "plugh": {
            "plove": {
                "find-this": "Here too!"
            }
        }
   }
}

所以,我想找到具有“发现,这个”领域的文件,以及(如果可能的话),以能够找到具有“发现,这个”字段的特定值的文档。

Answer 1:

你是对的BSON文档的某些语句不是一个XML文档。 由于XML被加载到一个树结构,包括“节点”的,上arbitary键搜索是很容易的。

一个MonoDB文件并非如此简单处理,这是在许多方面“数据库”,所以人们普遍预计将有数据的位置有一定的“一致性”,以使他们更容易的“指数”和搜索。

不过,这是可以做到。 但当然,这并不意味着在服务器上执行递归过程,这意味着JavaScript的处理与$where

作为一个基本的shell的例子,但一般的function只是一个字符串参数传递给$where运营商在其他地方:

db.collection.find(
  function () {
    var findKey = "find-this",
        findVal = "please find me";

    function inspectObj(doc) {
      return Object.keys(doc).some(function(key) {
        if ( typeof(doc[key]) == "object" ) {
          return inspectObj(doc[key]);
        } else {
          return ( key == findKey && doc[key] == findVal );
        }
      });
    }
    return inspectObj(this);
  }
)

所以基本上,目前测试对象中的键,看看他们是否匹配所需的“字段名”和内容。 如果这些关键之一恰好是一个“对象”,然后递归到的功能,并再次检查。

JavaScript的.some()可确保找到了“第一”的比赛将从搜索功能给人一种回归true结果,并返回,其中认为“键/值”是存在一定深度的对象。

请注意, $where基本上意味着你遍历整个集合,除非有其他有效的查询过滤器相比,可以适用于在集合的“指数”。

所以,小心使用,或者根本没有,只是用重新structring数据到一个更可行的形式工作。

但是,这会给你的比赛。



Answer 2:

这里有一个例子,我使用为重点,价值文档结构的任何地方递归搜索:

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;
        }       
    }    
})


文章来源: How to find MongoDB field name at arbitrary depth