Join CouchDB:从两个独立的emit获取唯一的文档?

Join CouchDB:从两个独立的emit获取唯一的文档?,join,graph,merge,nosql,couchdb,Join,Graph,Merge,Nosql,Couchdb,本质上,我在CouchDB中存储一个实体的有向图,并且需要能够找到进出图的边 设置: 目前存储数据的方式如下所示。每个文档表示两个实体之间的关系: doc: { entity1: { name: '' ... }, entity2: { name: '' ... } ... } 我有一个视图,它执行一系列的emit,其中两个emit文档是在其entity1组件和entity2组件上键入的,因此类似于: function() { emit(['entity1',

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

设置:

目前存储数据的方式如下所示。每个文档表示两个实体之间的关系:

doc: {
    entity1: { name: '' ... },
    entity2: { name: '' ... }
    ...
}
我有一个视图,它执行一系列的emit,其中两个emit文档是在其entity1组件和entity2组件上键入的,因此类似于:

function() {
    emit(['entity1', doc.entity1.name]);
    emit(['entity2', doc.entity2.name]);
}
边是定向的,从entity1和entity2开始。因此,如果我想找到实体外的边,我只需查询第一个发射;如果希望边进入实体,则查询第二个发射

问题:

这里的问题在于,我还需要捕获进出实体的边。有没有办法将这两个发射分组或减少为一组[x]唯一对的双向发射


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

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

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(['other'[doc.entity1.name,“out”]],1);
emit(['other'[doc.entity2.name,“in”]],1);
emit(['out',doc.entity1.name],1);
emit(['in',doc.entity2.name],1);
}
然后您可以轻松地执行以下操作:

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


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

是的,几天前我尝试过类似的方法,除了在视图上明显更长的索引构建时间外,运行时性能与多视图方法非常接近。谢谢:)酷。One t值得注意的是,CouchDB在使用Javascript视图服务器时是令人失望的单线程(我猜Erlang视图服务器没有这个问题)。如果您想通过在多个CPU核上运行多个视图来提高性能,您需要将每个视图放在其自己的设计文档中(并触发所有视图的更新).当然,那么你们的观点可能并不完全一致。权衡取舍: