与 `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-A
和 Condition-B
只是不同过滤步骤的链接,例如 has
或 hasLabel
等
中间.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
时,遍历器将再次折叠回一个。
我正在跟进这两个问题 --
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-A
和 Condition-B
只是不同过滤步骤的链接,例如 has
或 hasLabel
等
中间.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
时,遍历器将再次折叠回一个。