根据链接文档的值减少CouchDB

时间:2012-01-26 04:42:27

标签: javascript couchdb

我们目前有一个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对减少视图无效”进行响应。

有关如何过滤此视图结果的任何建议吗?

2 个答案:

答案 0 :(得分:1)

我对CouchDB很新,但你应该阅读:

CouchDB Joins

所以我认为你需要做的是使用复杂的密钥和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);  
    }
}