0

我有一个带有已定义节点的图形数据库。我想找到结束节点,给定我的起始节点和最后一条边(结束节点所在的位置)。例如:

A-(knows)->B-(likes)->C-(shares)->D 其中 (....) 是关系

现在,如果我想问一个问题,给定一个节点“A”,给我它直接或间接“共享”的节点。那应该用'D'回复。所以基本上给出了一个开始节点,结束边缘我可以找到我想要的节点。

我的问题是,这在 Cypher(或者可能是 gremlin )中是否可能,如果是这样,那么正确的方法是什么?

4

2 回答 2

2

这是 Gremlin 与 jjaderberg 接受的答案相同的警告(即昂贵,因此可能有必要限制您在图中触摸的内容):

gremlin> g = new TinkerGraph()                                                                                   
==>tinkergraph[vertices:0 edges:0]
gremlin> g.loadGraphML('data/graph-example-2.xml')                                                               
==>null
gremlin> ends=[] as Set;g.v(1).as('x').outE.as('e').inV.sideEffect{v,m->if (m.e.label=="followed_by") {ends<<v}}.loop('x'){it.loops<3}.iterate()                 
==>null
gremlin> ends        
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
==>v[50]
...

为了稍微分解一下该语句,我基本上构建了一个称为 Set 的集合ends,我们将在其中聚合在“followed_by”边的末尾找到的唯一顶点。我们从顶点开始1,遍历所有边到顶点……本质上是 Gremlin 的这一部分:

g.v(1).as('x').outE.as('e').inV

sideEffect然后,如果它们是通过“followed_by”标签来的,那么我将这些顶点放入集合中。我认为在 Gremlin 中有时会忽略两个参数步骤闭包sideEffect……您可以在此处了解更多信息。该语句通过在管道上循环以从这些顶点进一步遍历而结束。我以 3 步强制中断循环。

于 2013-10-30T12:40:03.647 回答
1

模式“开始节点和最后一条边是已知的,找到结束节点”可以在 Cypher 中表示为

START a=node:nodeIndex({indexQueryParam})
MATCH a-[?*]->()-[:SHARES]->d
RETURN d

?声明这部分模式是可选的,并且它*可以是任意长度。您可能不需要两者,因为可变长度可能意味着长度为零,但是在您进一步充实您的模式时请记住两者。由于您并不真正想要该B节点,因此您不必绑定它——空括号就可以了。

但是,这种模式非常普遍,并且根据您的数据,它可能会很昂贵(这有点像用炸药钓鱼)。您给出了您可能希望在图中找到的其他关系类型的示例,KNOWS并且LIKES。任何类似你可以引入来指定你的模式的东西都会让你的查询表现得更好。

MATCH a-[?:KNOWS|LIKES*]->()-[:SHARES]->d

或者如果您知道这些将按什么顺序发生

MATCH a-[?:KNOWS]->()-[LIKES*]->()-[:SHARES]->d

这里KNOWS图案的部分只有一深,而LIKES部分是零到无穷深。该KNOWS部分是可选的,这意味着a通过这个可选部分链接到的模式的整个部分也是可选的。

最后,让可变深度范围在零和无穷大之间通常不是一个好主意。引入对您的数据有意义的上限和/或下限,如下所示

MATCH a-[?:KNOWS]->()-[LIKES*1..4]->()-[:SHARES]->d

您将不得不查看您在数据中找到(或强加于)数据的模式,并相应地开发您的密码查询模式,始终尽可能多地指定密码模式,只留下您想要填充的未定义部分在图中。

于 2013-10-29T10:53:01.530 回答