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

cej*_*ast 9 gremlin tinkerpop3

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

g.V()
  .hasLabel('person').has('name', 'John')
  .fold()
  .coalesce(
    __.unfold(),
    g.addV('person').property('name', 'John')
  ).next();
Run Code Online (Sandbox Code Playgroud)

折叠/展开的目的是什么?为什么这些是必要的,为什么这不起作用:

g.V()
  .coalesce(
    __.hasLabel('person').has('name', 'John'),
    g.addV('person').property('name', 'John')
  ).next();
Run Code Online (Sandbox Code Playgroud)

折叠然后展开的模式对我来说似乎是多余的,但上述情况并没有产生相同的结果.

ste*_*tte 12

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

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> 
Run Code Online (Sandbox Code Playgroud)

对于"marko",你会返回一些东西而对于"stephen"则不会."斯蒂芬"案是值得关注的案例,因为fold()在这种格局中,这种​​情况真正变得重要.如果该遍历没有返回任何内容,那么在此之后添加的任何步骤将不会有Traverser用于触发这些步骤中的操作的存在.因此,即使以下内容也不会添加顶点:

gremlin> g.V().has('name','stephen').addV('person')
gremlin> 
Run Code Online (Sandbox Code Playgroud)

但看看如果我们fold():

gremlin> g.V().has('name','stephen').fold()
==>[]
Run Code Online (Sandbox Code Playgroud)

fold()是一个减少障碍的步骤,因此将热切地评估到那一点的遍历并将内容作为一个返回,List即使遍历到那一点的遍历的内容不产生任何东西(在这种情况下,你可以看到,你得到一个空列表).如果你有一个空的List那个空ListTraverser流过遍历,那么未来的步骤将会触发:

gremlin> g.V().has('name','stephen').fold().addV('person')
==>v[13]
Run Code Online (Sandbox Code Playgroud)

所以,这就是我们为什么fold(),因为我们检查"约翰"在你的例子的存在,如果他发现了,然后他会在存在List和当List与"约翰"打coalesce()了第一次检查将是unfold()那个List与"约翰",并返回Vertex - 完成.如果List是空的并且没有返回因为"John"不存在那么它将添加顶点(顺便说一句,你不需要前面的"g." addV(),它应该只是一个匿名遍历,因此__.addV('person')).

谈到你的例子,我首先要指出我想你想问这个问题:

g.V().
  coalesce(
    __.has('person','name', 'John'),
    __.addV('person').property('name', 'John'))
Run Code Online (Sandbox Code Playgroud)

这是一个完全不同的查询.在这个遍历中,你要说的是迭代所有顶点,并且每个顶点执行中的顶点coalesce().您可以通过替换以下内容addV()来清楚地看到这一点constant('x'):

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
Run Code Online (Sandbox Code Playgroud)

现在,想象一下addV()和"约翰" 会发生什么.它将调用addV()6次,每次顶点遇到一次不是"John":

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]
Run Code Online (Sandbox Code Playgroud)

就个人而言,我喜欢在结束了这种逻辑的想法小鬼DSL -有这样做的一个很好的例子在这里.

好问题 - 我已经将"元素存在"问题描述为可以在这里阅读的Gremlin食谱的一部分.