0

我想找到应该链接到给定节点的节点,其中链接由一些逻辑定义,该逻辑使用节点和现有边的属性,逻辑如下:

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

B) 该对具有不同的 zip 并且 name_similarity > 0.5 或

C)该对具有边缘类型“external_info”,值为“connect”)

D)AND(该对没有带有“external info”的边缘类型,值为“disconnect”)

简而言之:(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,节点 E 不应链接。

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

4

1 回答 1

0

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

  • 顶点 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'),所以您的情况涉及相对较小的图形(可能在内存中),并且此查询将起作用,或者您需要一起找到另一种方法。也许您有进一步限制“b”的方法,这可能会有所帮助?如果沿着这些路线的东西是可能的,我可能会尝试更好地定义边缘遍历的方向性以避免bothE(),而不是限制outE()inE()将摆脱otherV(). 希望您使用允许以顶点为中心的索引的图形,这也可以加快“分数”上的边缘查找(不确定这是否会对“决策”有很大帮助,因为它的选择性很低)。

于 2020-08-07T12:17:17.470 回答