为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

犯罪嫌疑人X 2019-08-23 09:24:51

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

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

我目前正在将每个Document拉到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!"
            }
        }
   }}

所以,我想找到具有“find-this”字段的文档,并且(如果可能的话)能够找到具有“find-this”字段的特定值的文档。


查看完整描述

2 回答

?
MMMHUHU

您在BSON文档的某些声明中是正确的不是XML文档。由于XML被加载到包含“节点”的树结构中,因此搜索任意键非常容易。

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实际上意味着遍历整个集合,除非有一些其他有效的查询过滤器可以应用于集合上的“索引”。

因此,请谨慎使用,或者根本不使用,只需将数据重新组织成更可行的形式即可。

但这会给你你的比赛。


查看完整回答
反对 回复 2019-08-23
?
慕盖茨4494581

这是一个例子,我用它来在文档结构的任何地方递归搜索Key-Value:

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


查看完整回答
反对 回复 2019-08-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信