0

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

设置:

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

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

我有一个执行一堆发射的视图,其中两个发射在其 entity1 组件和它们的 entity2 组件上键入的文档,例如:

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

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

问题:

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

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

4

1 回答 1

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]

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

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

于 2012-08-09T18:56:40.307 回答