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

时间:2013-12-28 02:33:26

标签: neo4j graph-databases orientdb titan

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

但是,我遇到了一个问题:我需要能够以某种方式定义三向关系。我还没有确定数据库,但我一直在修补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之间创建边缘,那么我的问题就变成:有没有一种好方法可以确保边缘和超边缘一起被移除?基本上,让两者都感觉像是一种解决方案,而不是一种实际的解决方案。

3 个答案:

答案 0 :(得分:6)

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

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

就遍历而言,我不能说我完全遵循你的意思,并且递归地遍历&#34;。如果你能详细说一下,我可以尝试修改我的答案。我将添加这个简单的例子,介绍如何从&#34; a&#34;找到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之间创建边缘   创造超边缘,然后我的问题变成:有一个好方法   确保边缘和超边缘一起被移除?

当您删除&#34; hyperedge&#34;顶点,您将自动删除与其相连的边缘,因此您可以有效地将它们一起移除。

答案 1 :(得分:3)

是否有一个特定的图形数据库本身支持这种类型的功能?

确实有! Grakn支持本机超边,其语法称为relation。匹配关系及其相关元素的最简洁方式如下:

match ($a, $b, $r) isa E; get;

完全公开:我在Grakn工作;)

答案 2 :(得分:0)

在Neo4j的文档中查看Hyperedges模式。