什么是Tinkerpop相当于Neo4j匹配/加入属性值

时间:2013-07-08 17:14:38

标签: neo4j gremlin tinkerpop

我有Neo4j Cypher个问题。我想了解如何在Tinkerpop / Gremlin(不是Neo4j实施)中执行相同的查询。

start
  f=node:node_auto_index('_Element:field OR _Element:dynamicField'),
  t=node:node_auto_index(_Element = 'fieldType')
where
  f.type=t.name
return
  f, t

基本上,我得到两种类型的节点(标签/类型/无论如何),并尝试通过属性值匹配找到一个指向另一个节点的位置。然后,我将使用结果创建一个真实的关系。

图表不是很大,最多可达数千个节点。

1 个答案:

答案 0 :(得分:2)

与任何事情一样,有很多方法可以解决这个问题。由于您有一个小数据集,我认为在Gremlin管道中对g.V进行查找并不是一个问题。为了模拟你的问题,我创建了自己的问题:使用toy graph,向任何具有sameFirstLetter属性的顶点添加lang边到具有age属性的任何顶点并且各自name属性的第一个字母相同。在这种情况下,它应该添加两个顶点,从5到4和从3到4。

gremlin> g = TinkerGraphFactory.createTinkerGraph()                                                                  
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V.has('lang').transform{v->[v,g.V.has('age').filter{it.name.startsWith(v.lang[0])}.toList()]}.sideEffect{edgeList->edgeList[1].each{it.each{edgeList[0].addEdge('sameFirstLetter',it)}}}
==>[v[3], [v[4]]]
==>[v[5], [v[4]]]
gremlin> g.E
==>e[1][5-sameFirstLetter->4]
==>e[10][4-created->5]
==>e[0][3-sameFirstLetter->4]
==>e[7][1-knows->2]
==>e[9][1-created->3]
==>e[8][1-knows->4]
==>e[11][4-created->3]
==>e[12][6-created->3]

此代码有两部分。第一个构造匹配的adjacency list,第二个构建边缘。这是获得邻接列表的部分:

g.V.has('lang').transform{v->[v,g.V.has('age').filter{it.name.startsWith(v.lang[0])}.toList()]}

上面的代码基本上说,抓住所有具有lang属性的顶点(请注意,has的使用是最新版Gremlin的一部分 - 即将发布的2.4.0。在2.4.0之前,您可以执行.hasNot('lang',null)或类似的操作),然后将它们转换为列表,其中列表中的第一项是lang顶点,列表中的第二项是列表图表中的顶点与name的第一个字母匹配,第一个字母为lang(在这种情况下为j个顶点的字母lang)。

.sideEffect{edgeList->edgeList[1].each{it.each{edgeList[0].addEdge('sameFirstLetter',it)}}}

上面的sideEffect正在处理此输出...邻接列表:

==>[v[3], [v[4]]]
==>[v[5], [v[4]]]

此操作可以作为单独的代码行执行(并非所有Gremlin都需要写在一行中......尽可能令人满意)。您可以简单地将邻接列表存储到变量中,然后对其进行后处理以创建边缘。无论如何,我选择在这里使用sideEffect,我循环创建边缘的列表列表。

或者,您也可以通过构建在属性值上键入的内存索引,然后将其用作查找来构建邻接列表,从而对数据集进行两次传递。通过这种方式,您只需要通过顶点列表两次:

gremlin> m=g.V.groupBy{it.name[0]}{it}.cap.next()
==>v=[v[2]]
==>r=[v[5]]
==>p=[v[6]]
==>l=[v[3]]
==>m=[v[1]]
==>j=[v[4]]
gremlin> g.V.has('lang').transform{[it,m[it.lang[0]]]}
==>[v[3], [v[4]]]
==>[v[5], [v[4]]]

这会使您进入与上一个示例中相同的邻接列表。通过邻接列表创建边缘仍然如前所述执行。