首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在任意深度找到MongoDB字段名

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

Stack Overflow用户
提问于 2015-07-03 02:45:16
回答 2查看 9.6K关注 0票数 18

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

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

下面是一个示例文档:

代码语言:javascript
复制
{
    "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”字段特定值的文档。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-03 06:56:00

在BSON文档的某些语句中,您是正确的,而不是XML文档。由于XML被加载到由“节点”组成的树结构中,因此在任意密钥上进行搜索非常容易。

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

然而,这是可以做到的。但是,这当然意味着在服务器上执行递归进程,这意味着使用JavaScript处理$where

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

代码语言:javascript
复制
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);
  }
)

因此,基本上,测试对象中的键,看看它们是否匹配所需的“字段名”和内容。如果其中一个键恰好是"object“,那么将其递归到函数中,然后再次检查。

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

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

所以,小心使用,或者根本不使用,只需将数据重构成更可行的形式即可。

但这会给你的对手。

票数 16
EN

Stack Overflow用户

发布于 2016-04-29 09:13:33

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

代码语言:javascript
复制
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;
        }       
    }    
})
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31197652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档