给出起始节点和结束边缘的图形中的结束节点

时间:2013-10-29 04:12:17

标签: neo4j cypher gremlin

我有一个包含已定义节点的图形数据库。我想找到终端节点,给定我的起始节点和最后一个边缘(终端节点存在)。例如:

A-(知道) - > B-(喜欢) - > C-(股) - > d 其中(....)是关系

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

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

2 个答案:

答案 0 :(得分: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]
...

为了稍微破坏该语句,我基本上构造了一个名为ends的Set,在其中我们将聚合在“followed_by”边缘末尾找到的唯一顶点。我们从顶点1开始,遍历所有边到顶点......基本上是Gremlin的这一部分:

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

然后我sideEffect将这些顶点插入到Set中,如果它们是通过“followed_by”标签来的话。在{Gremlin}中,sideEffect的两个参数步骤闭包有时会被忽略...我想...你可以阅读更多关于here的信息。该语句以循环回管道结束,从这些顶点进一步遍历。我强行打破循环3步。

答案 1 :(得分:1)

模式'起始节点和最后一个边缘是已知的,找到终端节点'可以在Cypher中声明为

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

?表示模式的这一部分是可选的,而*表示它可以是任意长度。您可能不需要两者,因为可变长度可能意味着长度为零,但在您进一步充实模式时请记住这两者。因为你真的不想要B节点,所以你不必绑定它 - 空括号没问题。

然而,这种模式非常普遍,根据您的数据,它可能很昂贵(这有点像用炸药钓鱼)。您可以提供您可能希望在图表KNOWSLIKES中找到的其他关系类型的示例。您可以通过引入来指定模式的任何内容将使您的查询表现更好。

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

或者如果您知道这些将发生在哪个顺序

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

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

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

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

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