【问题标题】:CouchDB: Get unique documents from two separate emits?CouchDB:从两个单独的发射中获取唯一的文档?
【发布时间】:2012-07-31 21:42:38
【问题描述】:

本质上,我在 CouchDB 中存储实体的有向图,并且需要能够找到图的进出边。

设置:

现在存储数据的方式如下。每个文档代表两个实体之间的关系:

doc: {
    entity1: { name: '' ... },
    entity2: { name: '' ... }
    ...
}

我有一个视图,它执行了一堆发射,其中两个发射的文档键控在它们的 entity1 组件和它们的 entity2 组件上,所以类似于:

function() {
    emit(['entity1', doc.entity1.name]);
    emit(['entity2', doc.entity2.name]);
}

边是有向的,从 entity1 和 entity2 出发。所以如果我想找到一个实体的边缘,我只需查询第一个发射;如果我想让边缘进入实体,我会查询第二个发射。

问题:

这里的问题在于我还需要捕获进入实体的边缘。有没有办法可以将这两个发射分组或减少为一组 [x] UNIQUE 对的双向集合?

有没有更好的方法来组织我的观点来宣传这一行动?

【问题讨论】:

    标签: join graph merge nosql couchdb


    【解决方案1】:

    最好只创建第二个视图。但是没有什么能阻止你像这样将各种不同的数据塞进同一个视图中:

    function() {
        if (doc.entity1.name == doc.entity2.name) {
          emit(['self-ref', doc.entity1.name], 1);
        }
        emit(['both'   [doc.entity1.name, doc.entity2.name]], 1);
        emit(['either' [doc.entity1.name, "out"]], 1);
        emit(['either' [doc.entity2.name, "in"]], 1);
        emit(['out', doc.entity1.name], 1);
        emit(['in', doc.entity2.name], 1);
    }
    

    然后您可以轻松地执行以下操作:

    • 找到所有的自我参考:
      • startkey=["self-ref"]&endkey=["self-ref", {}].
    • 查找特定节点的所有边(传入或传出):
      • startkey=["either", [nodeName]]&endkey=["either", [nodeName, {}]]
      • 如果你不减少这个,那么你仍然会在键中保留“in”与“out”。如果您从不需要查询具有传入或传出边的 所有 节点,则可以将最后两个发射替换为“任一”发射。
    • 从 node1 -> node2 找到所有边:
      • key=["both", [node1, node2]

    以及您对特定节点的传入或传出的原始查询。

    我建议您先对应用程序的典型用例进行基准测试,然后再选择这种组合视图方法或多视图方法。

    【讨论】:

    • 是的,我几天前尝试了类似的方法,除了视图上的索引构建时间明显更长之外,运行时性能非常接近多视图方法。谢谢:)
    • 酷。需要注意的一点是,在使用 Javascript 视图服务器时,CouchDB 令人失望的是单线程(我猜 Erlang 视图服务器没有这个问题)。如果您想通过在多个 CPU 内核上运行多个视图来提升性能,您需要将每个视图放在其自己的设计文档中(并触发所有视图的更新)。当然,那么您的观点可能不会立即相互一致。权衡取舍。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 2015-02-15
    相关资源
    最近更新 更多