Neo4j 如何构造图形数据库以支持三方关系?

Neo4j 如何构造图形数据库以支持三方关系?,neo4j,graph-databases,orientdb,titan,Neo4j,Graph Databases,Orientdb,Titan,我一直在尝试为我一直在开发的个人网络应用程序设计一个数据库后端。由于我在数据中要求的灵活性,关系数据库是不可行的,可能需要某种形式的文档存储。当我学习图形数据库时,我觉得这将是完美的 然而,我遇到了一个问题:我需要能够以某种方式定义一个三方关系。我还没有决定要建立一个数据库,但我一直在修补Neo4j,所以我将使用Cypher来描述这个问题 基本上,我从以下几点开始: (a:N)-[r:E]->(b:N) 我需要的是一种将多个节点不仅关联到a和b,还关联到r的方法。这些其他节点将存储关于所

我一直在尝试为我一直在开发的个人网络应用程序设计一个数据库后端。由于我在数据中要求的灵活性,关系数据库是不可行的,可能需要某种形式的文档存储。当我学习图形数据库时,我觉得这将是完美的

然而,我遇到了一个问题:我需要能够以某种方式定义一个三方关系。我还没有决定要建立一个数据库,但我一直在修补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)
match ($a, $b, $r) isa E; get;
然而,一旦我将边拉出到超边中,我就不知道是否有一种方法能够递归地遍历图形到一个不确定的深度,因为我将是交替的节点类型。我在找一些类似于

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

如果答案只是在创建超边的同时在a和b之间创建边,那么我的问题是:是否有一种好方法可以确保边和超边一起删除?基本上,两者兼有感觉就像是一种变通方法,而不是一个实际的解决方案。

请查看Neo4j文档中的模式。

您描述的场景是由所提到的hyperedge pattern@Pangea在属性图模型中处理的。实际上,您可以将边(需要进出边)转换为顶点。对于图形,我认为它不是一种非规范化,而是一种不同的建模抽象

就边对边的本机支持而言,您标记问题的所有图形都不直接支持这样的功能。由于您包括了Titan和OrientDB,我假设您也在评估TinkerPop作为解决方案的一部分,我可以进一步说,由于蓝图不支持边对边,因此没有一个蓝图图也支持边对边

至于遍历,我不能说我完全遵循了你所说的“递归遍历”的意思。如果你能详细说明一下,我可以试着修改我的答案。我将添加一个简单的示例,说明如何从“a”顶点遍历以查找Gremlin中的所有其他相关顶点(对不起,我不知道Cypher):

gremlin>g=newTinkergraph()
==>tinkergraph[顶点:0边:0]
gremlin>va=g.addVertex([类型:'N',名称:'a'])
=>v[0]
gremlin>er=g.addVertex([类型:'R',名称:'R'])
=>v[1]
gremlin>vb=g.addVertex([类型:'N',名称:'b'])
=>v[2]
gremlin>vc=g.addVertex([类型:'N',名称:'c'])
=>v[5]
小妖精>弗吉尼亚州的阿迪奇('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([类型:'N',名称:'d'])
=>v[7]
gremlin>es=g.addVertex([类型:'R',名称:'s'])
=>v[8]
gremlin>vb.addEdge('e',es)
==>e[9][2-e->8]
小精灵>vd.addEdge('e',es)
==>e[10][7-e->8]
小精灵>x=[];va.aggregate(x).out.in.除了(x).loop(4){it.loopsc
==>b
gremlin>x=[];va.aggregate(x).out.in.except(x).loop(4){it.loopsd
关于:

如果答案只是在a和b之间创建一条边 创建超边缘,然后我的问题变成:有好的方法吗 确保边和超边一起删除

删除“超边”顶点时,将自动删除与其连接的边,因此可以有效地将它们一起删除

是否有特定的图形数据库本机支持此类功能

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

(a:N)<-[:E]-(r:R)->[:E](b:N)
(s:S)->(a)
(s)->(r)
(s)->(b)
match ($a, $b, $r) isa E; get;

完整披露:我在Grakn工作。)

你能详细说明一下吗?我之前看到过,但它似乎并没有解决我的递归问题。我能收集到的最好的信息是,也许我应该在a和b之间创建一条边,同时创建关系节点,这将允许两个世界的最佳结合。然而,这将被称为非规范化在一个关系数据库中,这通常是不受欢迎的,但似乎在这里被显示为一个功能,所以我不确定我是否完全明白。链接已经死了。请你提供更多关于这意味着什么的信息好吗?我已经更新了OP,提供了更多关于我要寻找的内容的信息。我列出了这三个,因为它们是came在我的脑海中浮现。我真的在寻找能够解决我所有问题的任何类型的数据库,而图形数据库是最接近这一点的。我只是还没有找到完美的数据库。更新了我的答案。回应了如何删除给定此模型的“hyperedge”,并扩展了我的代码以包含一些“深度”你可以循环遍历到任意深度(同样,抱歉…我不知道密码)。图形在建模时提供了一些非常丰富的抽象…虽然使用顶点作为你认为的边可能感觉不自然,但可能不是这样。图形是关于事物和事物之间的关系…有时,图形是一个“关系”本身可以被认为是一种“事物”,如果你的领域需要它,那也没关系。我的问题是:如果我有(a:N)[:E](b:N),那么我必须创建(a)-[E:E]->(b)为了递归地遍历我的N类节点,即a->b->c->d,或者有没有方法在每个节点之间创建超边?因为它现在看起来像a->r1->b->r2->c->r3->d。如果我创建超边,我正在寻找一种不必创建超边的方法