【问题标题】:How to list the nodes associated to a given vertex through intermediate nodes in TinkerPop3?如何通过 TinkerPop3 中的中间节点列出与给定顶点关联的节点?
【发布时间】:2017-05-13 01:03:18
【问题描述】:

我在 TinkerPop3 中有一个图,其中节点通过具有给定权重的边连接。

给定图中的节点 A,我试图遍历它以获取可以从 A 到达的所有节点,步骤少于 N,并按分数对它们进行排序。该分数是通过将路径中的每条边映射到该边的权重除以步数和总步数,最后对列表求和来计算的。

这是一个例子:

gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> a = g.addV('name','a').next()
==>v[0]
gremlin> b = g.addV('name','b').next()
==>v[2]
gremlin> c = g.addV('name','c').next()
==>v[4]
gremlin> d = g.addV('name','d').next()
==>v[6]
gremlin> e = g.addV('name','e').next()
==>v[8]
gremlin> a.addEdge('conn', b, 'weight', 1)
==>e[10][0-conn->2]
gremlin> a.addEdge('conn', c, 'weight', 3)
==>e[11][0-conn->4]
gremlin> b.addEdge('conn', d, 'weight', 3)
==>e[12][2-conn->6]
gremlin> d.addEdge('conn', e, 'weight', 9)
==>e[14][6-conn->8]

与“a”相关的节点的预期分数是:

score_n = sum_over_n(weight_n-1n / (depth_n * total_N_from_a_to_n))
score_b = w_ab / (1 * 1) = 1 / 1 = 1
score_c = w_ac / (1 * 1) = 3 / 1 = 3
score_d = (w_ab / (1 * 2)) + (w_bd / (2 * 2)) = 1/2 + 3/4 = 5/4
score_e = (w_ab / (1 * 3)) + (w_bd / (2 * 3)) + (w_de / (3 * 3)) = 1/3 + 3/6 + 9/9 = 11/6

因此,结果应该是相应的节点降序排列:

c e d b

我是 TinkerPop 和 Gremlin 的新手,我一直在尝试将重复步骤和 sack 步骤结合起来,但没有运气。到目前为止的计划是为每次遍历累积一个麻袋中的步骤,发出分数和节点,最后按分数排序,但我担心与该过程相关的潜在性能问题。

【问题讨论】:

  • 你能添加你尝试但没有工作的查询吗?从现在开始可能比从头开始更容易。
  • 此外,如果您能提供示例图表和预期结果,那将是有益的。
  • @DanielKuppitz 我添加了一个示例和预期结果:)
  • @AlaaMahmoud 我的查询还远远没有工作,所以不值得分享。即使我在描述中添加了一个示例。

标签: titan gremlin tinkerpop


【解决方案1】:

不是从 TinkerPop 开始的最简单的遍历。我改变的第一件事是权重的数据类型。

graph = TinkerGraph.open()
g = graph.traversal()
a = g.addV('name','a').next()
b = g.addV('name','b').next()
c = g.addV('name','c').next()
d = g.addV('name','d').next()
e = g.addV('name','e').next()
a.addEdge('conn', b, 'weight', 1f)
a.addEdge('conn', c, 'weight', 3f)
b.addEdge('conn', d, 'weight', 3f)
d.addEdge('conn', e, 'weight', 9f)

这是消除舍入错误所必需的。它也可以作为遍历的一部分来完成,但我不想添加更多步骤,因为它已经变得足够复杂了:

gremlin> g.withSack(0).V().has("name","a").
           repeat(outE("conn").as("e").values("weight").as("w").
                  sack(assign).by(loops()).sack(sum).by(constant(1)).sack().as("l").
                  select("e").inV().as("v").select("v","w","l").as("x").select("v")).emit().
           select(all, "x").as("x").
           count(local).as("c").select("x").
           map(unfold().sack(assign).by(select("w")).
                        sack(div).by(select("l")).
                        sack(div).by(select("c")).sack().fold()).
           project("score","v").by(sum(local)).by(select("x").tail(local, 1).select("v")).
           order().by(select("score"), decr).select("v").values("name")
==>c
==>e
==>d
==>b

更新

以下是 TP 3.0.1 的有效遍历:

gremlin> Gremlin.version()
==>3.0.1-incubating
gremlin> g.withSack(0D).V().has("name","a").
           repeat(outE("conn").as("e").values("weight").as("w").
                  select(all,"w").count(local).as("l").
                  select(last,"e").inV().as("v").select(last,"v","w","l").as("x").select("v")).emit().
           select(all,"x").as("x").
           count(local).as("c").select(last,"x").
           map(unfold().as("m").select("w").sack(sum).
               select(last,"m").select("l").sack(div).
               select(last,"m").select("c").sack(div).sack().fold()).as("score").
           select(last, "score","x").by(sum(local)).by(tail(local, 1).select("v")).
           order().by(select("score"), decr).select("x").values("name")
==>c
==>e
==>d
==>b

这种遍历的唯一好处是,weight 属性不必具有其他数据类型 - int 可以正常工作。

【讨论】:

  • 哇!那太棒了。我原以为它会很复杂,但没有那么复杂。我怀疑我是否会找到解决方案,所以非常感谢。尽管如此,当我在 gremlin 控制台中运行它时,我不断收到一个神秘的错误,上面写着:“没有这样的属性:为类分配:groovysh_evaluate”。我确定它必须与我的本地配置相关,但您知道它与什么相关吗?其他运算符正常工作,例如 mult 或 sum。
  • 啊,我才发现。我正在使用依赖于 TinkerPop 3.0.1 的 Titan 1.0,但是在 TinkerPop 3.1.0 中添加了分配运算符。
  • 糟透了,泰坦已经远远落后了。没有assign sack 是毫无用处的。今天晚些时候我会尝试重写遍历。不要指望它会变得更简单:)。
  • 别担心,我会尝试为 Titan 1.1 编译 dev 分支,看看它是否有效。我已经占用你太多时间了!
  • 查看 TP 3.0.1 版本的遍历更新。
猜你喜欢
  • 2022-12-14
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
相关资源
最近更新 更多