Gremlin - 在节点和边属性上查找具有多个布尔条件的连接节点

Gremlin - finding connected nodes with several boolean conditions on both nodes and edges properties

我想找到应该 linked 到给定节点的节点,其中 link 由某些逻辑定义,该逻辑使用节点和现有边的属性以及以下内容逻辑:

A)(该对具有相同的 zip(节点属性)和 name_similarity(边缘属性)> 0.3 OR

B) 这对有不同的 zip 且 name_similarity > 0.5 或

C) 该对的边类型为“external_info”,值为“connect”)

D) AND(该对没有带“外部信息”且值为“断开连接”的边类型)

简而言之: (A | B | C) & (~D)

我还是 gremlin 的新手,所以我不确定如何在边和节点上组合多个条件。

下面是创建图表的代码,以及该图表的预期结果:

# creating nodes

(g.addV('person').property('name', 'A').property('zip', '123').
addV('person').property('name', 'B').property('zip', '123').
addV('person').property('name', 'C').property('zip', '456').
addV('person').property('name', 'D').property('zip', '456').
addV('person').property('name', 'E').property('zip', '123').
addV('person').property('name', 'F').property('zip', '999').iterate())

node1 = g.V().has('name', 'A').next()
node2 = g.V().has('name', 'B').next()
node3 = g.V().has('name', 'C').next()
node4 = g.V().has('name', 'D').next()
node5 = g.V().has('name', 'E').next()
node6 = g.V().has('name', 'F').next()

# creating name similarity edges

g.V(node1).addE('name_similarity').from_(node1).to(node2).property('score', 1).next() # over threshold
g.V(node1).addE('name_similarity').from_(node1).to(node3).property('score', 0.2).next() # under threshold
g.V(node1).addE('name_similarity').from_(node1).to(node4).property('score', 0.4).next() # over threshold
g.V(node1).addE('name_similarity').from_(node1).to(node5).property('score', 1).next() # over threshold
g.V(node1).addE('name_similarity').from_(node1).to(node6).property('score', 0).next() # under threshold

# creating external output edges

g.V(node1).addE('external_info').from_(node1).to(node5).property('decision', 'connect').next() 
g.V(node1).addE('external_info').from_(node1).to(node6).property('decision', 'disconnect').next() 

输入节点 A 的预期输出是节点 B(由于条件 A)、D(由于条件 B)和 F(由于条件 C)。由于条件 D.

,不应 link 编辑节点 E

我正在寻找将检索这些结果的 Gremlin 查询。

鉴于您预期的输出,您的数据似乎有问题所以我不得不进行更正:

  • 顶点 D 不会出现在结果中,因为“分数”小于 0.5
  • "external_info" 边缘似乎颠倒了

这是我使用的数据:

g.addV('person').property('name', 'A').property('zip', '123').
addV('person').property('name', 'B').property('zip', '123').
addV('person').property('name', 'C').property('zip', '456').
addV('person').property('name', 'D').property('zip', '456').
addV('person').property('name', 'E').property('zip', '123').
addV('person').property('name', 'F').property('zip', '999').iterate()
node1 = g.V().has('name', 'A').next()
node2 = g.V().has('name', 'B').next()
node3 = g.V().has('name', 'C').next()
node4 = g.V().has('name', 'D').next()
node5 = g.V().has('name', 'E').next()
node6 = g.V().has('name', 'F').next()
g.V(node1).addE('name_similarity').from(node1).to(node2).property('score', 1).next() 
g.V(node1).addE('name_similarity').from(node1).to(node3).property('score', 0.2).next() 
g.V(node1).addE('name_similarity').from(node1).to(node4).property('score', 0.6).next() 
g.V(node1).addE('name_similarity').from(node1).to(node5).property('score', 1).next() 
g.V(node1).addE('name_similarity').from(node1).to(node6).property('score', 0).next() 
g.V(node1).addE('external_info').from(node1).to(node6).property('decision', 'connect').next() 
g.V(node1).addE('external_info').from(node1).to(node5).property('decision', 'disconnect').next() 

我采用了以下方法:

gremlin> g.V().has('person','name','A').as('a').
......1>   V().as('b').
......2>   where('a',neq('b')).
......3>   or(where('a',eq('b')).                                                    // A
......4>        by('zip').
......5>      bothE('name_similarity').has('score',gt(0.3)).otherV().where(eq('a')), 
......6>      bothE('name_similarity').has('score',gt(0.5)).otherV().where(eq('a')), // B
......7>      bothE('external_info').                                                // C
......8>        has('decision','connect').otherV().where(eq('a'))).
......9>   filter(__.not(bothE('external_info').                                     // D
.....10>                 has('decision','disconnect').otherV().where(eq('a')))).
.....11>   select('a','b').
.....12>    by('name')
==>[a:A,b:B]
==>[a:A,b:D]
==>[a:A,b:F]

我认为这包含您正在寻找的所有逻辑,但我没有花很多时间对其进行优化,因为我认为任何优化都不会解决 V().as('b'),所以要么你的情况涉及一个相对较小的图(in-memory 可能)并且这个查询可以工作,要么你需要一起找到另一种方法。也许您有进一步限制“b”的方法,这可能会有所帮助?如果沿着这些方向的东西是可能的,我可能会尝试更好地定义边缘遍历的方向性以避免 bothE() 而是限制为 outE()inE() 这将摆脱 otherV().希望您使用的图形允许以顶点为中心的索引,这也可以加快“分数”上的边缘查找速度(不确定这是否对“决策”有很大帮助,因为它的选择性较低)。