gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 22:25:33 25 4
gpt4 key购买 nike

我一直在尝试为我一直在开发的个人 Web 应用找出数据库后端。由于我在数据中需要的灵 active ,关系数据库不可行,某种形式的文档存储是可能的。当我了解图数据库时,我觉得这将是完美的。

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

最佳答案

您描述的场景由提到的超边模式@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

关于:

If the answer is just to also create an edge between a and b while creating the hyper edge, then my question becomes: is there a good way to ensure that the edge and hyper edge are removed together?

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

关于neo4j - 如何构建图形数据库以支持三向关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20810418/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com