无论文档中的归档位置如何,任何noSql数据库都可以按特定字段获取数据吗?

时间:2011-06-26 15:27:08

标签: mongodb couchdb nosql

例如,如果在DB中有这些文档:

> db.things.find()
[ 
  {"_id" : {"$oid" : "4e0748eecc93747e680421c7"},
          "title" : "aaaa"},
  {"_id" : {"$oid" : "4e074954cc93747e680421c8"},
          "desc" : "bbb",
          "children" : [
            {"title" : "ccc"},
            {"title" : "ddd"}
            ]
  }
  {"_id" : {"$oid" : "4e074a5abbdr4664546e59334"},
          "desc" : "none",
          "children" : [
            {"desc" : "ccc"}
            ]
  }
]

我希望得到所有包含“title”字段的文档,我不知道该字段在文档中的位置。 Mongodb / Couchdb或任何其他文档db是否有这种查询选项?

2 个答案:

答案 0 :(得分:3)

您可以使用CouchDB Map-Reduce查询来完成此任务。您需要编写一个函数,以递归方式搜索文档中的指定字段。由于CouchDB仅以递增方式更新视图索引,因此只有在每次创建或更新文档时才会进行搜索。

如果你想要一些实际的源代码来编写这样的地图函数,我相信我可以鞭打一些东西。但CouchDB可以实现。 :)

编辑:我花了几分钟时间来破解递归扫描功能。它没有经过全面测试,但如果它不起作用,应该是一个非常好的开始。

我为类型测试添加了几个便利函数,主函数名为scan。它需要2个参数,一个输入和一个函数来调用每个匹配。

它将循环输入。如果输入是一个对象,它将检查该对象的键,如果是一个数组,它将以递归方式为数组中的每个项调用scan。一旦输入是一个对象,它将检查每个键,如果名称是title,它将使用值作为第一个参数调用传递的函数。否则,它会调用scan,以防该值是另一个对象或数组。

在map函数的末尾,它传入文档,以及一个只用标题值调用emit的函数。

function (doc) {
    function is_array(input) {
        return (input.constructor.toString().indexOf("Array") != -1);
    }

    function is_object(input) {
        return (typeof input === "object" && input !== null);
    }

    function scan(obj, func) {
        if (!obj || !is_object(obj)) {
            return false;
        }

        var x;

        if (is_object(obj)) {
            for (x in obj) {
                if (x.toLowerCase() === "title") {
                    func(obj[x]);
                } else {
                    scan(obj[x], func);
                }
            }
        } else if (is_array(obj)) {
            for (x = 0; x <= obj.length; x++) {
                scan(obj[x], func);
            }
        }
    }

    scan(doc, function (value) {
        emit(value);
    });
}

答案 1 :(得分:2)

这样的搜索无处不在的功能在MongoDB中是不可用的 - 至少不是开箱即用而不是通用的方式。使用处理嵌套文档的相关实现的Map-Reduce是一个选项,或者应用程序端过滤是另一个选项。