这个查询在neo4j / gremlin中是否可行?

时间:2012-07-23 22:41:14

标签: neo4j graph-databases gremlin

如果我的图表看起来像:

N3->member_of->N1
N2->knows->N1
N3->likes->N2
N4->member_of->N1
N5->likes->N2

是否有办法执行以下操作的单个查询:

  1. 如果在N3开始将返回N2
  2. 在N4开始的相同查询将返回N2
  3. 从N5开始的相同查询将返回N2
  4. (最好是在gremlin中)

    编辑:澄清:只要第一级关系是“member_of”,我就可以通过二级连接。

5 个答案:

答案 0 :(得分:3)

相当古老的问题,但由于没有人想出Gremlin解决方案,所以这是:

我使用了Bobbys初始化脚本:

g = new TinkerGraph()
(1..5).each { g.addVertex(it) }
g.addEdge(g.v(3), g.v(1), "member_of") 
g.addEdge(g.v(2), g.v(1), "knows")
g.addEdge(g.v(3), g.v(2), "likes")
g.addEdge(g.v(5), g.v(2), "likes") 
g.addEdge(g.v(4), g.v(1), "member_of")

这是你的Gremlin查询:

gremlin> g.v(3).copySplit(_().out('likes'), _().out('member_of').loop('start'){true}{true}.in('knows')).exhaustMerge().dedup()
==>v[2]
gremlin> g.v(4).copySplit(_().out('likes'), _().out('member_of').loop('start'){true}{true}.in('knows')).exhaustMerge().dedup()
==>v[2]
gremlin> g.v(5).copySplit(_().out('likes'), _().out('member_of').loop('start'){true}{true}.in('knows')).exhaustMerge().dedup()
==>v[2]

干杯, 丹尼尔

答案 1 :(得分:0)

这就是它在cypher中的样子:

1: start n=node(3) match n-[:LIKES]->m return m;
2: start n=node(4) match n-[:MEMBER_OF]-m-[]-k return k;  (will return n2,n3. if you want n2 only match n-[:MEMBER_OF]-m-[:KNOWS]-k )
3: the same as 1)

答案 2 :(得分:0)

不确定您的设置是否正确,请尝试在此处执行此操作:http://tinyurl.com/d2mjkj2 - 设置正确吗?

如果第一个关系类型需要为member_of,则N5不应返回N2。否则,您可以执行类似

的操作
start s=node(3,4,5) match s-[r1:member_of]->()<-[r2*0..1]-end return s,end

返回以member_of关系开头的模式,然后具有任意类型的0或1个关系。如果需要,请将其加强,有关详细信息,请参阅http://docs.neo4j.org/chunked/snapshot/query-match.html#match-variable-length-relationships

答案 3 :(得分:0)

首先使用Gremlin Groovy shell

TinkerGraph中创建图表
g = new TinkerGraph()
(1..5).each { g.addVertex(it) }
g.addEdge(g.v(3), g.v(1), "member_of") 
g.addEdge(g.v(2), g.v(1), "knows")
g.addEdge(g.v(3), g.v(2), "likes")
g.addEdge(g.v(5), g.v(2), "likes") 
g.addEdge(g.v(4), g.v(1), "member_of")

听起来你想要一个从顶点3,4或5开始并返回顶点2的查询。下面的查询使用算法:

  • 获取顶点'x'
  • 获取传入和传出的相邻顶点
  • 再循环两次,直到我们循环3次或找到id为“2”的顶点
  • 通过获取管道的next()成员来获得Dedup结果
gremlin> g.v(3).both.loop(1) {it.loops < 3}{it.object.id == "2"}.next()
==>v[2]
gremlin> g.v(4).both.loop(1) {it.loops < 3}{it.object.id == "2"}.next()
==>v[2]
gremlin> g.v(5).both.loop(1) {it.loops < 3}{it.object.id == "2"}.next()
==>v[2]

您可能还会发现path pattern上的Gremlin文档很有用。

答案 4 :(得分:0)

您是否希望返回某个人所属的任何组的所有相关节点(人?),的所有传入和传出关系?那么“团体”会将他们的关系归结为“成员”吗?

如果是这样,并且假设不允许使用递归组,我会想出一个替代图表,可以更清楚地说明您的用例(据我所知) - &gt; http://console.neo4j.org/?id=wyr207

如果你跑

start n=node(5) match n-[?:knows|likes]-related, n-[?:member_of]->group-[:knows|likes]-other_related return related, other_related
如果节点是组的成员,则图表上的

related返回所有直接相关的节点,并other_related从组返回的所有其他节点。将这些组合起来超出了我的Cypher能力,但它们将被删除AFAIK(related中的节点将不包含在other_related中)。

使用几个不同的节点ID(N5的节点ID为1)在控制台链接中尝试查询,看看这是否是您的想法。添加关系方向等很简单。

将它转换为Gremlin是一个 tad 位乏味(Cypher中的模式匹配更自然),但LMK如果这是正确的方向,我会这样做。