【问题标题】:Reducing CouchDB based on value from linked document根据链接文档的值减少 CouchDB
【发布时间】:2013-06-04 16:33:36
【问题描述】:

我们目前有一个 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 不应返回,因为它是私有的。

我似乎无法在 map 阶段过滤结果,因为我只有 doc id,而不是要检查的整个文档。我尝试使用链接文档功能将文档添加到键中,并在地图的 emit 中包含 {'_id': doc.forked_from},但 CouchDB 以“include_docs 对减少视图无效”进行响应。

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

【问题讨论】:

  • 您的意思是原始文档是公开的吗?还是叉子?
  • 我是指原文档的权限,我加了一个例子来帮助澄清。

标签: javascript couchdb


【解决方案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}
]}

我希望这可以帮助您解决问题。

【讨论】:

    【解决方案2】:

    你说你只有 _id,但你已经检查了 doc.forked_from 的存在,所以肯定 doc.permissions 必须可用?

    所以你的地图功能肯定是……

    function (doc) {
        if (doc.doctype === 'entry' && doc.forked_from && doc.permissions === 'public') {  
            emit(doc.forked_from, 1);  
        }
    }  
    

    【讨论】:

    • 我已经很久没有做这个了,所以我不能回去轻松测试。但我认为这不太正确,因为我仍然想计算从公共文档中分叉的私人文档,您的地图不包括这些。
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 2020-05-31
    • 1970-01-01
    相关资源
    最近更新 更多