Gremlin 为什么需要使用coalesce对条件插入进行折叠/展开?

Gremlin 为什么需要使用coalesce对条件插入进行折叠/展开?,gremlin,tinkerpop3,Gremlin,Tinkerpop3,我试图了解条件插入的这种模式是如何工作的: g.V() .hasLabel('person').has('name', 'John') .fold() .coalesce( __.unfold(), g.addV('person').property('name', 'John') ).next(); 折叠/展开的目的是什么?为什么这些是必要的,为什么这不起作用: g.V() .coalesce( __.hasLabel('person').has(

我试图了解条件插入的这种模式是如何工作的:

g.V()
  .hasLabel('person').has('name', 'John')
  .fold()
  .coalesce(
    __.unfold(),
    g.addV('person').property('name', 'John')
  ).next();
折叠/展开的目的是什么?为什么这些是必要的,为什么这不起作用:

g.V()
  .coalesce(
    __.hasLabel('person').has('name', 'John'),
    g.addV('person').property('name', 'John')
  ).next();

“折叠然后展开”模式对我来说似乎是多余的,但上面的结果并不相同。

考虑一下,当您只执行以下操作时会发生什么:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('name','marko')
==>v[1]
gremlin> g.V().has('name','stephen')
gremlin> 
对于“marko”你会返回一些东西,而对于“stephen”你不会。“stephen”案例值得注意,因为在这种模式中,
fold()
确实变得非常重要。当该遍历不返回任何内容时,在此之后添加的任何步骤都不会出现
遍历器来触发这些步骤中的操作。因此,即使以下操作也不会添加顶点:

gremlin> g.V().has('name','stephen').addV('person')
gremlin> 
但是看看如果我们折叠()会发生什么:

fold()
是一个减少障碍的步骤,因此将急切地评估到该点的遍历并将内容作为
列表返回,即使到该点的遍历内容没有产生任何结果(在这种情况下,正如您所看到的,您会得到一个空列表)。如果您有一个空的
列表
,则该空的
列表
是一个通过遍历的
遍历器
,因此未来的步骤将触发:

gremlin> g.V().has('name','stephen').fold().addV('person')
==>v[13]
这就解释了为什么我们要折叠()
,因为我们在你的例子中检查“John”的存在,如果他被找到,那么他将存在于
列表中,当带有“John”的
列表点击
合并()
时,它的第一个检查将是
展开()
带有“John”的
列表中并返回
顶点
-完成。如果
列表
为空,并且由于“John”不存在而不返回任何内容,那么它将添加顶点(顺便说一句,您不需要在
addV()
前面加上“g.”,它应该只是一个匿名遍历,因此
\uuuuuuuuuuuuuuuuuuuu.addV('person')

关于你的例子,我想首先指出,我想你想问一下:

g.V().
  coalesce(
    __.has('person','name', 'John'),
    __.addV('person').property('name', 'John'))
这是一个完全不同的查询。在本次遍历中,您说的是迭代所有顶点,并对每个顶点执行
coalesce()
中的内容。通过将
addV()
替换为
常量('x')
,您可以非常清楚地看到这一点:

现在,想象一下
addV()
和“John”会发生什么。它将调用
addV()
6次,对于它遇到的不是“John”的每个顶点调用一次:

就我个人而言,我喜欢把这种逻辑用a来包装——这是一个很好的例子


好问题-我已经将“元素存在”问题描述为可以阅读的小精灵食谱的一部分。

有趣的模式相关:很好的解释非常有用。
g.V().
  coalesce(
    __.has('person','name', 'John'),
    __.addV('person').property('name', 'John'))
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().
......1>   coalesce(
......2>     has('person','name', 'John'),
......3>     constant('x'))
==>x
==>x
==>x
==>x
==>x
==>x
gremlin> g.V().
......1>   coalesce(
......2>     has('person','name', 'marko'),
......3>     constant('x'))
==>v[1]
==>x
==>x
==>x
==>x
==>x
gremlin> g.V().
......1>   coalesce(
......2>     __.has('person','name', 'John'),
......3>     __.addV('person').property('name', 'John'))
==>v[13]
==>v[15]
==>v[17]
==>v[19]
==>v[21]
==>v[23]