我们目前有一个CouchDB数据库,其中包含一些从其他文档创建的文档。这用文档中的“forked-from”字段表示。
例如:
{
"_id":"doc_1",
"_rev":"1-a23f9403a1d86648b2a304f5a4c78c31",
"doctype":"entry",
"data":"foo",
"permissions":"private"
}
{
"_id":"doc_2",
"_rev":"1-9c15e43a8c8d4ce1b00af94b328d268d",
"doctype":"entry",
"data":"bar",
"forked_from":"doc_1"
"permissions":"public"
}
{
"_id":"doc_3",
"_rev":"1-b13c761e43121c074c44736826f3ce7e",
"doctype":"entry",
"data":"bat",
"forked_from":"doc_2"
"permissions":"private"
}
我们目前有一个map / reduce视图,它将返回文档分叉的次数,它告诉我们最受欢迎的文档是什么。
function (doc) {
if (doc.doctype === 'entry' && doc.forked_from) {
emit(doc.forked_from, 1);
}
}
function(keys, values, rereduce) {
return sum(values);
}
,使用group=true
查询此视图的结果将是:
{"rows":[
{"key":"doc_1","value":1},
{"key":"doc_2","value":1}
]}
但是,我们希望只返回权限设置为“public”的文档,以便查询结果如下所示:
{"rows":[
{"key":"doc_2","value":1}
]}
不应该返回 doc_1
,因为它是私有的。
似乎我不能在地图阶段过滤结果,因为我只有文档ID,而不是要检查的整个文档。我尝试使用链接文档功能将文档添加到密钥,并在地图的{'_id': doc.forked_from}
中包含emit
,但CouchDB以“include_docs对减少视图无效”进行响应。
有关如何过滤此视图结果的任何建议吗?
答案 0 :(得分:1)
我对CouchDB很新,但你应该阅读:
所以我认为你需要做的是使用复杂的密钥和group_level。这样做的方法是构建地图函数:
function (doc) {
if (doc.doctype === 'entry' && doc.forked_from) {
emit([doc.permissions, doc.forked_from], 1);
}
}
结果将是这样的,使用group = true:
{"rows":[
{"key":["private", "doc_1"],"value":1},
{"key":["public", "doc_2"],"value":1},
{"key":["private", "doc_3"],"value":1},
]}
为了只获取“公共”文档,您必须使用范围查询和group_level查询参数:
http://localhost/db/_design/entry/_view/getNumberForked?startkey=["public", 0]&endkey=["public", {}]&group_level=2
这会给你结果:
{"rows":[
{"key":["public", "doc_2"],"value":1}
]}
我希望这可以帮助您解决问题。
答案 1 :(得分:0)
你说你只有_id,但你已经检查过doc.forked_from的存在,所以肯定doc.permissions必须可用吗?
所以你的地图功能肯定会......
function (doc) {
if (doc.doctype === 'entry' && doc.forked_from && doc.permissions === 'public') {
emit(doc.forked_from, 1);
}
}