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()
.希望您使用的图形允许以顶点为中心的索引,这也可以加快“分数”上的边缘查找速度(不确定这是否对“决策”有很大帮助,因为它的选择性较低)。
我想找到应该 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()
.希望您使用的图形允许以顶点为中心的索引,这也可以加快“分数”上的边缘查找速度(不确定这是否对“决策”有很大帮助,因为它的选择性较低)。