简体   繁体   English

TinkerPop gremlin 仅在 path() 中计算顶点

[英]TinkerPop gremlin count vertices only in a path()

When I make a query of a path eg:当我查询路径时,例如:

g.V(1).inE().outV().inE().outV().inE().outV().path()

There are both vertices and edges in the path(), is there any way to count the number of vertices in the path only and ignore edges? path() 中既有顶点又有边,有没有办法只计算路径中的顶点数而忽略边?

Gremlin is missing something important to make this really easy to do - it doesn't discern types very well for purposes of filtering, thus TINKERPOP-2234 . Gremlin 遗漏了一些重要的东西来使这变得非常容易 - 它不能很好地识别类型以进行过滤,因此TINKERPOP-2234 I've altered your example a bit so that we could have something a little trickier to work with:我对您的示例进行了一些更改,以便我们可以使用一些更棘手的东西:

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]]

With repeat() we get variable length Path instances so dynamic counting of the vertices is a bit trickier than the fixed example you have in your question where the pattern of the path is known and a count is easy to discern just from the Gremlin itself.使用repeat()我们得到可变长度的Path实例,因此顶点的动态计数比您在问题中的固定示例有点棘手,其中路径的模式是已知的,并且计数很容易从 Gremlin 本身中辨别出来。 So, with a dynamic number of vertices and without TINKERPOP-2234 you have to get creative.因此,使用动态数量的顶点并且没有 TINKERPOP-2234,您必须发挥创造力。 A typical strategy is to just filter away the edges by way of some label or property value that is unique to vertices:一个典型的策略是通过一些 label 或顶点特有的属性值来过滤掉边缘:

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

Or perhaps use an property unique to all edges:或者也许使用所有边独有的属性:

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

If you don't have these properties or labels in your schema that allows for this you could probably use your traversal pattern to come up with some math to figure it out.如果您的架构中没有这些属性或标签允许这样做,您可能会使用您的遍历模式来提出一些数学来解决它。 In my case, i know that my Path will always be (pathLength + 1) / 2 so:就我而言,我知道我的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

Hopefully, one of those ways will inspire you to a solution.希望其中一种方法能激发您找到解决方案。

+1 for typeOf predicate support in Gremlin (TINKERPOP-2234). +1 用于 Gremlin 中的typeOf谓词支持 (TINKERPOP-2234)。

In addition to @stephan's answer, you can also mark and select only vertices:除了@stephan 的回答,您还可以仅标记和 select 顶点:

g.V().repeat(outE().inV().as('v')).times(3).select(all,'v')

Also, if the graph provider support it, you can also use {it.class} :此外,如果图形提供程序支持它,您还可以使用{it.class}

g.V().repeat(outE().inV().as('v')).times(3).path()
    .map(unfold().groupCount().by({it.class}))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM