如何在 TinkerPop 图中传播值

Posted

技术标签:

【中文标题】如何在 TinkerPop 图中传播值【英文标题】:How to propagate a value in a TinkerPop graph 【发布时间】:2017-04-24 09:11:04 【问题描述】:

如何通过 TinkerPop 图表“传播”一个值?即给定一个顶点上的属性值,我想将该值沿边“移动”到另一个顶点或一组顶点。

例如,给定这个由 3 个顶点和 2 条连接它们的边组成的简单图:

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','amount', 100).next()
==>v[0]
gremlin> b = g.addV('name','b','amount', 0).next()
==>v[3]
gremlin> c = g.addV('name','c','amount', 0).next()
==>v[6]
gremlin> a.addEdge('drain', b, 'factor', 0.5)
==>e[9][0-drain->3]
gremlin> b.addEdge('drain', c, 'factor', 0.1)
==>e[10][3-drain->6]
gremlin> 

我希望在此图上运行某种操作,以便将a 中的amount 复制到b 乘以连接它们的边缘中的factor。例如。 b['amount'] 将等于 50。然后进一步传播 c['amount'] 将等于 5。

理想情况下,我想知道一个语句可以一次将值传播到整个链,但也有一个语句可以将它传播到第一个相邻的顶点,然后在第二次调用时将它传播到下一个顶点等。

这是可以简单地在 Gremlin 中完成的事情,还是我需要 TinkerPop 的其他部分?

【问题讨论】:

【参考方案1】:

我设法使用 Gremlin sacks 做到了这一点:

gremlin> g.withSack(a.value('amount')).
           V(a).repeat(outE('drain').sack(mult).by('factor').
                       inV().property('amount', sack())).
                until(__.outE('drain').count().is(0)).iterate()
gremlin> g.V().valueMap()
==>[amount:[100],name:[a]]
==>[amount:[50.0],name:[b]]
==>[amount:[5.00],name:[c]]

我将“sack value”初始化为等于顶点“a”中的“amount”并开始遍历,迭代地遍历我们将sack中的值乘以(即mult)的“drain”边“排水”边缘上的“因子”属性。然后通过property() 步骤将麻袋分配给下一个顶点。

请注意,您可以在repeat 上使用适当的循环语义来控制“排水”(即您想在链条上走多远)。现在它使用until()“没有更多的传出边缘”。但是您也可以按如下方式终止仅一步之遥:

gremlin> g.withSack(a.value('amount')).
           V(a).repeat(outE('drain').sack(mult).by('factor').
                       inV().property('amount', sack())).
                times(1).iterate()
gremlin> g.V().valueMap()
==>[amount:[100],name:[a]]
==>[amount:[50.0],name:[b]]
==>[amount:[0],name:[c]]

【讨论】:

太棒了,谢谢!如果我想进一步扩展一般问题,以便在每个顶点上都有关于值是否传播的逻辑,也许值本身可能是顶点上几个属性的函数,是否会编写一个 VertexProgam 在GraphComputer 是要走的路吗?它们必须用 Java 编写,还是可以使用 python 变体? 在上面添加这些附加功能不会太难,也不需要 VertexProgram。为了防止传播,您只需要控制循环,因此让您的until() 评估顶点属性以确定它是否应该中断。如果您需要更复杂的逻辑来增加 sack,有几个选项:首先,您可以将调用链接到 sack()。其次,您可以使用 lambda 来修改 sack 值。归根结底,sack() 方法只需要一个BiFunction,所以计算可以做任何你想做的事情。 'mult' 只是一个辅助运算符。 VertexProgram 实例必须用 java 编写。它们是核心 API 的一部分,并未扩展到 GLV(Gremlin 语言变体)。 好的,谢谢您的信息。我要解决的下一个问题不是像上面那样沿着链传播值,而是如何通过导致它的边缘属性中的值来增加/减少顶点上的属性。我将把它写成一个单独的问题,不过一旦我尝试了几次。

以上是关于如何在 TinkerPop 图中传播值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Gremlin/Titan/TinkerPop3 更新特定的边缘属性?

[吃药深度学习随笔] 前向传播:即如何在图中输入数据向前推进从而得到计算结果

前项传播和反向传播

Laravel 8 + Tinker:如何创建虚拟数据

TinkerPop简述

引入 Tinker 之后如何在 Debug 模式下开启 Instant Run