neo4j - Neo4j 属性值匹配/连接的 Tinkerpop 等价物是什么

标签 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

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

图不是很大,最多几千个节点。

最佳答案

与任何事情一样,有很多方法可以解决这个问题。由于您的数据集很小,因此我认为在 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 的第一个字母匹配的顶点列表code> (在本例中,两个 lang 顶点均使用字母 j)。

.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]]]

这将使您获得与上一个示例中找到的相同的邻接列表。通过邻接列表创建边仍然按照前面提到的那样执行。

关于neo4j - Neo4j 属性值匹配/连接的 Tinkerpop 等价物是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17532361/

相关文章:

gremlin - 如何处理具有大量边的顶点?

neo4j - 没有为该数据库实例注册名称为 `apoc.help` 的过程

performance - Neo4j和OpenLink Virtuoso

database - 如何将社交网络关系 csv(列表字典)文件导入 neo4j 图形数据库?

c# - Gremlin if else inside .by() 函数

azure - Cosmos DB : Gremlin API Request too large exception. 如何重试调用

gremlin - Tinkerpop Gremlin 清除控制台不工作

neo4j - 使用 neo4jphp 函数 "relateTo"在两个节点之间创建双向关系

nosql - 获取沿路径具有特定属性、标签和 ID 的所有顶点

gremlin - 合并顶点,包括属性和传入/传出边