与 `select` 和 `as` 的 gremlin 交集

gremlin intersection with `select` and `as`

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

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

我正在大量查看 Whosebug(想感谢社区!)但不幸的是我没有 post/write 很多,所以我什至没有足够的声誉 post 对上面的 post 发表评论...因此我在这里问我的问题..

在上面的第 2 个 post 中,Hieu 和我一起工作,我想提供更多关于这个问题的背景信息。

正如斯蒂芬在评论中所问的那样(对于第二个 post),我想在中间链接 V() 的原因仅仅是因为我想从头开始遍历,即整个图的每个节点就像 g.V() 所做的那样,它出现在 gremlin documentation.

中大多数查询的开头

更多说明:假设我需要对结果进行 2 个条件过滤器。基本上我想写

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

借用了 Stephen 在第一个 post 中的回答中的最后一个答案。这里 Condition-ACondition-B 只是不同过滤步骤的链接,例如 hashasLabel

中间.V()处应该写什么?或者是否有其他方式来编写查询,以便 Condition-B 完全独立于 Condition-A?

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

再次感谢 Kelvin 和 Stephen。很高兴和兴奋地与编写了 book/wrote gremlin 源代码的您联系。

在遍历过程中,V() 被应用到前面步骤创建的每个遍历器。考虑这个使用航线数据集的例子:

g.V(1,2,3)

这将产生三个结果:

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

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

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

我们得到 3,747 个结果。如果我们现在这样做:

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 遍历的流程。您可以将查询视为 containing/spawning 一个或多个并行流(它可能不会以这种方式执行,但从概念上讲,它有助于我以这种方式思考)。因此 g.V('1') 创建一个流(我们通常将它们称为遍历器)。但是,如果有多个出边来自 V('1')g.V('1').out() 可能会创建多个遍历器。当遇到 fold 时,遍历器将再次折叠回一个。