带有`selt`和`as`的gremlin交集

人气:774 发布:2022-10-16 标签: gremlin janusgraph tinkerpop

问题描述

我正在跟进这两个问题--

gremlin intersection operation

JanusGraph Gremlin graph traversal with `as` and `select` provides unexpected result

我正在密切关注StackOverflow(想感谢社区!)但不幸的是,我没有太多的帖子/文章,所以我甚至没有足够的声誉在上面的帖子上发表评论……所以我在这里问我的问题。

在上面的第二个帖子中,Hieu和我一起工作,我想就这个问题提供更多的背景信息。

正如Stephen在评论(第二篇)中所问的那样,我想在中间链接V()的原因很简单,因为我想从头开始遍历,即整个图的每个节点都像g.V()所做的那样,它出现在gremlindocumentation中大多数查询的开头。

更多一点的说明:假设我需要对结果进行2个条件筛选。基本上我想写

g.V().(Condition-A).as('setA')
 .V().(Condition-B).as('setB')
 select('setA').
 where('setA',eq('setB'))

它借用了Stephen在第一篇帖子中的答案。这里Condition-ACondition-B只是不同筛选步骤的链接,如hashasLabel等。

我应该在中间.V()的位置写什么?或者有没有其他方法来编写查询,使Condition-B完全独立于Condition-A

最后,我阅读了https://tinkerpop.apache.org/docs/3.5.0/reference/#graph-step查询中间的V()链接部分。我仍然不能完全理解第二个帖子的奇怪后果,也许我应该阅读更多关于遍历器如何工作的文章?

再次感谢凯尔文和斯蒂芬。很高兴与写了一本书/编写了Gremlin源代码的您联系。

推荐答案

在遍历过程中,将V()应用于前面步骤创建的每个遍历器。考虑使用AIR-ROUES数据集的以下示例:

g.V(1,2,3)

这将产生三个结果:

v[1]
v[2]
v[3]

如果我们计算图中的所有顶点:

gremlin> g.V().count()
==>3747 

我们得到3747个结果。如果我们现在这样做:

gremlin> g.V(1,2,3).V().count()
==>11241

我们得到了11,241个结果(正好是3747的3倍)。这是因为对于g.V(1,2,3)中的每个结果,我们都计算了图中的每个顶点。

编辑后添加:

如果需要聚合一些结果,然后使用这些结果作为过滤器再次浏览图表,一种方法是引入fold步骤。这将再次将所有的遍历器折叠为一个。这可确保第二个V步骤不会被任何先前的扇出重复多次。

gremlin> g.V(1,2,3).fold().as('a').V().where(within('a'))
==>v[1]
==>v[2]
==>v[3]

gremlin> g.V(1,2,3).fold().as('a').V().where(without('a')).limit(5)
==>v[0]
==>v[4]
==>v[5]
==>v[6]
==>v[7]    

再次编辑以添加:

我认为人们有时会纠结于Gremlin遍历流的关键部分。您可以认为一个查询包含/产生一个或多个并行流(它可能不是以这种方式执行的,但从概念上讲它有助于我以这种方式思考它)。因此g.V('1')创建一个流(我们通常将它们称为遍历器)。但是,如果有多条传出边源自V('1'),则g.V('1').out()可能会创建多个遍历。当遇到fold时,所有遍历都会再次折叠回一个。

248