如何构建图形数据库以支持3向关系?

jmb*_*mer 2 neo4j graph-databases orientdb titan

我一直在努力想出一个我一直在努力的个人网络应用程序的数据库后端.由于我在数据中需要的灵活性,关系数据库是不可行的,并且可能存在某种形式的文档存储.当我了解图形数据库时,我觉得这将是完美的.

但是,我遇到了一个问题:我需要能够以某种方式定义一个三向关系.我还没有确定数据库,但我一直在修补Neo4j,所以我将使用Cypher来描述这个问题.

基本上,我从这开始:

(a:N)-[r:E]->(b:N)
Run Code Online (Sandbox Code Playgroud)

我需要的是一种将多个节点不仅与a和b相关联的方法,还包括r.这些其他节点将存储有关所有3的不同信息.我认为可能只有两种方法来处理:将关系存储在自己的节点中或存储对包含信息的节点的引用并创建伪边缘.我认为前者可能是一个更好的主意,给我们更像这样的东西:

(a:N)<-[:E]-(r:R)->[:E](b:N)
(s:S)->(a)
(s)->(r)
(s)->(b)
Run Code Online (Sandbox Code Playgroud)

所以,现在,这会导致查询数据的问题.使用图形数据库的重点是能够遍历图形.如果我做这样的事情,有没有办法在N型节点之间递归遍历?处理这个问题的正确方法是什么?我已经想到了几种不同的处理方式,但是所有这些都有它们的缺点.是否有一个特定的图形数据库本机支持这种类型的功能?

UPDATE

使用原始代码,我能够使用以下代码递归遍历节点:

MATCH (a:N)-[:E*]->(b:N)
RETURN a,b
Run Code Online (Sandbox Code Playgroud)

然而,一旦我将边缘拉出到超边缘,我无法弄清楚是否有一种方法能够递归地遍历图形到未确定的深度,因为我将交替节点类型.我正在寻找一些类似的东西

MATCH chain=((a:N)-[]->(r:R)-[]->(b:N))*
RETURN [nodes of type N along the chain]
Run Code Online (Sandbox Code Playgroud)

如果答案只是在创建超边缘时也在a和b之间创建边缘,那么我的问题就变成:有没有一种好方法可以确保边缘和超边缘一起被移除?基本上,让两者都感觉像是一种解决方案,而不是一种实际的解决方案.

ste*_*tte 6

您描述的场景是在属性图模型中通过提到的超边界模式@Pangea处理的.您基本上将边缘(需要边缘进出)转换为顶点.通过图形,我认为它不像非规范化,而是更多的不同的建模抽象.

对于边缘边缘的原生支持,没有任何标记您的问题的图表直接支持这样的功能.正如您所做的那样包括Titan和OrientDB,我假设您正在评估TinkerPop作为解决方案的一部分,我可以进一步说,由于Blueprints不支持边缘边缘,所以Blueprints图也不会.

就遍历而言,我不能说我完全遵循"递归遍历"的意思.如果你能详细说一下,我可以尝试修改我的答案.我将添加这个简单的例子,说明如何从"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
Run Code Online (Sandbox Code Playgroud)

关于:

如果答案只是在创建超边缘时也在a和b之间创建边缘,那么我的问题就变成:有没有一种好方法可以确保边缘和超边缘一起被移除?

当您移除"hyperedge"顶点时,您将自动删除与其连接的边缘,因此您可以有效地将它们一起移除.