例如,如果数据库中有以下文档:
> 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"}
]
}
]
我想得到所有的文件,其中有“标题”字段,我不知道该字段在文件中的位置。
MongoDB/CouchDB或任何其他文档数据库是否有这种查询选项?
最佳答案
您可以通过couchdb map reduce查询来实现这一点。您需要编写一个函数,递归地搜索文档中指定的字段。由于couchdb只以增量方式更新视图索引,因此每次创建或更新文档时才进行搜索。
如果你想要一些实际的源代码来编写这样一个映射函数,我相信我可以激发一些东西。但是couchdb是有可能的。:)
编辑:我花了几分钟修改了一个递归扫描函数。它还没有完全测试过,但是如果还没有成功的话,对你来说应该是一个很好的开始。
我为类型测试添加了两个方便的函数,主函数名为scan
。它需要两个参数、一个输入和一个函数来调用每个匹配项。
它将循环输入。如果输入是一个对象,它将检查该对象的键;如果是数组,它将递归地为数组中的每个项调用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);
});
}