【发布时间】:2019-11-20 22:00:52
【问题描述】:
当我查询路径时,例如:
g.V(1).inE().outV().inE().outV().inE().outV().path()
path()中既有顶点又有边,有没有办法只统计路径中的顶点数而忽略边?
【问题讨论】:
当我查询路径时,例如:
g.V(1).inE().outV().inE().outV().inE().outV().path()
path()中既有顶点又有边,有没有办法只统计路径中的顶点数而忽略边?
【问题讨论】:
Gremlin 遗漏了一些重要的东西来使这变得非常容易 - 它不能很好地识别类型以进行过滤,因此 TINKERPOP-2234。我对您的示例进行了一些修改,以便我们可以处理一些更棘手的问题:
gremlin> g.V(1).repeat(outE().inV()).emit().path()
==>[v[1],e[9][1-created->3],v[3]]
==>[v[1],e[7][1-knows->2],v[2]]
==>[v[1],e[8][1-knows->4],v[4]]
==>[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]
==>[v[1],e[8][1-knows->4],v[4],e[11][4-created->3],v[3]]
使用repeat(),我们得到可变长度Path 实例,因此顶点的动态计数比您在问题中已知路径模式且计数很容易辨别的固定示例有点棘手来自 Gremlin 本身。因此,使用动态数量的顶点并且没有 TINKERPOP-2234,您必须发挥创造力。一个典型的策略是通过顶点唯一的一些标签或属性值过滤掉边缘:
gremlin> g.V(1).repeat(outE().inV()).emit().path().map(unfold().hasLabel('person','software').fold())
==>[v[1],v[3]]
==>[v[1],v[2]]
==>[v[1],v[4]]
==>[v[1],v[4],v[5]]
==>[v[1],v[4],v[3]]
gremlin> g.V(1).repeat(outE().inV()).emit().path().map(unfold().hasLabel('person','software').fold()).count(local)
==>2
==>2
==>2
==>3
==>3
或者也许使用所有边都独有的属性:
gremlin> g.V(1).repeat(outE().inV()).emit().path().map(unfold().not(has('weight')).fold())
==>[v[1],v[3]]
==>[v[1],v[2]]
==>[v[1],v[4]]
==>[v[1],v[4],v[5]]
==>[v[1],v[4],v[3]]
gremlin> g.V(1).repeat(outE().inV()).emit().path().map(unfold().not(has('weight')).fold()).count(local)
==>2
==>2
==>2
==>3
==>3
如果您的架构中没有这些属性或标签允许这样做,您可能会使用您的遍历模式提出一些数学来解决这个问题。就我而言,我知道我的Path 将永远是(pathLength + 1) / 2 所以:
gremlin> g.V(1).repeat(outE().inV()).emit().path().as('p').math('(p + 1) / 2').by(count(local))
==>2.0
==>2.0
==>2.0
==>3.0
==>3.0
希望其中一种方法能激发您找到解决方案。
【讨论】:
map 就可以了。尝试使用local,但得到了疯狂的结果 - 我对 tinkerPop 仍然太陌生,无法完全掌握文档:(
local() step 的使用有时需要对 Gremlin 的细微之处有一些微妙的了解 - stephen.genoprime.com/snippet/2020/04/25/snippet-10.html
+1 表示 Gremlin 中的 typeOf 谓词支持 (TINKERPOP-2234)。
除了@stephan 的回答,你还可以只标记和选择顶点:
g.V().repeat(outE().inV().as('v')).times(3).select(all,'v')
另外,如果图形提供者支持,你也可以使用{it.class}:
g.V().repeat(outE().inV().as('v')).times(3).path()
.map(unfold().groupCount().by({it.class}))
【讨论】: