我一直在尝试找出我一直在从事的个人Web应用程序的数据库后端。由于我在数据中需要灵活性,因此关系数据库不可行,并且可能以某种形式存储文档。当我了解图数据库时,我觉得这将是完美的。
但是,我遇到了一个问题:我需要能够以某种方式定义三向关系。我还没有决定使用哪个数据库,但是我一直在修改Neo4j,因此我将使用Cypher来描述问题。
本质上,我从以下开始:
(a:N)-[r:E]->(b:N)
我需要的是一种不仅将多个节点关联到a和b,还关联到r的方法。这些其他节点将存储有关所有3个节点的不同信息。我认为可能只有两种方法可以处理此问题:将关系存储在其自己的节点中或存储对包含该信息的节点的引用并创建伪边缘。我认为前者可能是一个更好的主意,为我们提供了以下更多信息:
(a:N)<-[:E]-(r:R)->[:E](b:N)
(s:S)->(a)
(s)->(r)
(s)->(b)
因此,现在,这导致了查询数据的问题。使用图形数据库的全部目的是能够遍历图形。如果我这样做,是否可以在N型节点之间递归遍历?处理此问题的正确方法是什么?我想到了几种不同的处理方法,但是它们都有缺点。是否有特定的图形数据库本身支持这种类型的功能?
更新
使用原始代码,我能够使用以下代码递归遍历节点:
MATCH (a:N)-[:E*]->(b:N)
RETURN a,b
但是,一旦将边缘拉到一个超边缘中,我就无法确定是否有一种方法可以递归地遍历该图到不确定的深度,因为我会交替使用节点类型。我正在寻找一些类似的东西
MATCH chain=((a:N)-[]->(r:R)-[]->(b:N))*
RETURN [nodes of type N along the chain]
如果答案是在创建超边缘时也要在a和b之间创建一条边缘,那么我的问题就变成了:是否有一种确保将边缘和超边缘一起去除的好方法?基本上,两者都感觉像是一种解决方法,而不是实际的解决方案。
最佳答案
您描述的场景是通过提到的hyperedge模式@Pangea在属性图模型中处理的。本质上,您需要将边缘(需要边缘进/出)转换为顶点。对于图,我会把它更多地看作是非规范化,而更多地是不同的建模抽象。
就对边缘上的边缘的原生支持而言,您标记问题的所有图表都没有直接支持这种功能。当您确实包括Titan和OrientDB时,我假设您也将TinkerPop评估为解决方案的可能部分,并且我可以进一步说,由于“蓝图”不支持边缘上的边缘,因此“蓝图”图也不支持。
就遍历而言,我不能说我完全遵循您所说的“递归遍历”。如果您可以详细说明,我可以尝试修改答案。我将添加一个简单的示例,说明如何从“ a”顶点遍历以找到Gremlin中的所有其他相关顶点(对不起,我不了解Cypher):
gremlin> g = new TinkerGraph()
==>tinkergraph[vertices:0 edges:0]
gremlin> va = g.addVertex([type:'N',name:'a'])
==>v[0]
gremlin> er = g.addVertex([type:'R',name:'r'])
==>v[1]
gremlin> vb = g.addVertex([type:'N',name:'b'])
==>v[2]
gremlin> vc = g.addVertex([type:'N',name:'c'])
==>v[5]
gremlin> va.addEdge('e',er)
==>e[3][0-e->1]
gremlin> vb.addEdge('e',er)
==>e[4][2-e->1]
gremlin> vc.addEdge('e',er)
==>e[6][5-e->1]
gremlin> va.out.in.except([va]).name
==>c
==>b
gremlin> vd = g.addVertex([type:'N',name:'d'])
==>v[7]
gremlin> es = g.addVertex([type:'R',name:'s'])
==>v[8]
gremlin> vb.addEdge('e',es)
==>e[9][2-e->8]
gremlin> vd.addEdge('e',es)
==>e[10][7-e->8]
gremlin> x=[];va.aggregate(x).out.in.except(x).loop(4){it.loops<2}.name
==>c
==>b
gremlin> x=[];va.aggregate(x).out.in.except(x).loop(4){it.loops<3}.name
==>d
关于:
如果答案仅仅是在a和b之间创建一条边,而
创建超级边缘,那么我的问题变成:有没有一种好的方法
确保将边缘和超边缘一起去除?
删除“超边缘”顶点时,将自动删除与其相连的边,因此可以有效地将它们一起删除。