CouchDB:从两个独立的发射中获取独特的文档?

时间:2012-08-02 20:53:58

标签: join graph merge nosql couchdb

基本上,我在CouchDB中存储实体的有向图,并且需要能够找到图中IN和OUT的边。

SETUP:

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

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

我有一个视图,它会发出一堆发射,其中两个发出的文件是在其entity1组件及其entity2组件上键入的,所以类似于:

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

边缘是指向的,从实体1和实体2开始。所以,如果我想找到一个实体的边缘,我只是查询第一个发射;如果我想让边进入一个实体,我会查询第二个发射。

问题:

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

是否有更好的方法来组织我的观点来推广此行动?

2 个答案:

答案 0 :(得分: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的所有边 - >节点2:
    • key=["both", [node1, node2]

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

我建议在选择这种组合视图方法或多视图方法之前对应用程序的典型用例进行基准测试。

答案 1 :(得分:0)

警告:我真的不明白你的“有向图”例子......

您是否有理由将所有这些案例塞进一个视图?只需创建第二个视图,其中包含您所追求的减少的发射配对。