Gremlin 小精灵合并步骤不一致(Cosmos DB/一般情况下?)

Gremlin 小精灵合并步骤不一致(Cosmos DB/一般情况下?),gremlin,Gremlin,合并不作为遍历的第一步工作,或者如果到达合并步骤的遍历未产生至少一个结果。在你回答这个问题之前,请听我说完 如果我在图形数据库中有一个label='foo'和id='bar'的顶点,并且我想添加一个label='baz'和id='caz'的顶点,那么下面的Gremlin查询非常有效 g.V('bar').coalesce(__.V('caz'), __.addV('baz').property('id', 'caz')) 如果;但是,我去掉了查询的第一部分,查询失败了 g.coalesce(_

合并不作为遍历的第一步工作,或者如果到达合并步骤的遍历未产生至少一个结果。在你回答这个问题之前,请听我说完

如果我在图形数据库中有一个label='foo'和id='bar'的顶点,并且我想添加一个label='baz'和id='caz'的顶点,那么下面的Gremlin查询非常有效

g.V('bar').coalesce(__.V('caz'), __.addV('baz').property('id', 'caz'))
如果;但是,我去掉了查询的第一部分,查询失败了

g.coalesce(__.V('caz'), __.addV('baz').property('id', 'caz'))
类似地,如果我按照如下方式重新处理查询,它也会失败

g.V('caz').coalesce(__.V('caz'), __.addV('baz').property('id', 'caz'))
为了使合并工作,它必须有一个由一个或多个元素组成的输入集。我理解为什么当合并步骤中的步骤是has和hasLabel时,这种方法是有意义的;但是,这对于V和addV来说没有意义。我猜coalesce的服务器实现有一个null或空输入步骤的检查/返回,这将取消对该步骤的处理

如果这是Gremlin的一个bug或改进请求,那么解决这个问题就太棒了。如果这是Cosmos DB唯一的问题,我将直接与Microsoft记录一个电话

在此期间,我正在拼命寻找一种解决方案,以应对仅在元素不存在时创建元素的挑战。我知道将折叠/展开与合并一起使用;但是,这会使以前定义的别名使用as'xyz'不可用,从而终止我的遍历上下文。考虑到我们正在编写的查询的复杂性,我们不能失去上下文;我们也负担不起在大规模处理数据时仅仅为了展开而进行的折叠计算

如有任何上述建议,我们将不胜感激

亲切问候,,
Seb

您不能使用Gremlin语言中的任何步骤开始遍历。有一些特定的开始步骤触发遍历,我所说的触发器是指它们将遍历器放置在管道中进行处理。实际上只有几个开始步骤:V、E和inject、addV和addE

我知道将折叠/展开与合并一起使用;但是,这会破坏我的遍历上下文,使以前使用as'xyz定义的别名不可用

通常情况下,你不应该过于依赖于它,好像它是可以避免的。许多像通常一样大量使用的遍历可以以其他形式重新编写。既然你没有更多的细节,我就不能进一步说明了

我们也负担不起在大规模处理数据时仅仅为了展开而进行的折叠计算

我无法想象折叠和展开会带来巨大的成本。在最坏的情况下,它会创建一个包含单个项目的列表,在最好的情况下,它会创建一个空列表。在类似的事情成为您关注的根本改进之前,您可能还有很多其他性能优化需要解决

综上所述,我想你可以做到:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.inject(1).coalesce(V().has('id','caz'),addV('baz').property('id','caz'))
==>v[0]
gremlin> g.inject(1).coalesce(V().has('id','caz'),addV('baz').property('id','caz'))
==>v[0]

您可以使用inject和一次性值开始遍历,以便在管道中输入一些内容。我认为我更喜欢折叠和展开的方法,因为我相信它更具可读性。我还将确保验证我所使用的图形是否实际使用了一个索引,用于合并中嵌入的中间遍历V。我希望所有的图表都能很好地进行这样的优化,但我不能完全肯定这一点。从这个意义上说,折叠和展开工作得更好,因为它们提供了一种更独立于平台的方式来执行查询。

您不能用Gremlin语言的任何步骤开始遍历。有一些特定的开始步骤触发遍历,我所说的触发器是指它们将遍历器放置在管道中进行处理。实际上只有几个开始步骤:V、E和inject、addV和addE

我知道将折叠/展开与合并一起使用;但是,这会破坏我的遍历上下文,使以前使用as'xyz定义的别名不可用

通常情况下,你不应该过于依赖于它,好像它是可以避免的。许多像通常一样大量使用的遍历可以以其他形式重新编写。既然你没有更多的细节,我就不能进一步说明了

我们也负担不起在大规模处理数据时仅仅为了展开而进行的折叠计算

我无法想象折叠和展开会带来巨大的成本。在最坏的情况下,它会创建一个包含单个项目的列表,在最好的情况下,它会创建一个空列表。在类似的事情成为您关注的根本改进之前,您可能还有很多其他性能优化需要解决

综上所述,我想你可以做到:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.inject(1).coalesce(V().has('id','caz'),addV('baz').property('id','caz'))
==>v[0]
gremlin> g.inject(1).coalesce(V().has('id','caz'),addV('baz').property('id','caz'))
==>v[0]
您可以使用inject和一次性值开始遍历,以便在管道中输入一些内容。我认为我更喜欢折叠和展开的方法,因为我相信它更具可读性。我还将确保验证我所使用的图形是否实际使用了一个索引,用于合并中嵌入的中间遍历V。我希望所有的图表都能很好地进行这样的优化,但是
我不能完全肯定地说。从这个意义上说,折叠和展开工作更好,因为它们提供了一种更独立于平台的方式来执行您的查询。

经过一些挖掘,我意识到问题是特定于Gremlin语言的,而不是特定于服务器实现的,而不是Cosmos DB的问题。因此,我使用了两种addif-not-exists模式

对于上下文,我们使用Gremlin配方提供程序模式,它确保在整个产品中为常见任务维护通用约定。因此,当我有一个要创建的元素边或顶点时,我将其传递给配方提供者,以返回带有addE/addV和生成的属性语义的遍历。这个问题源于生成支持addif-notexists模式的配方

为了解决这个问题,我向配方提供程序传递一个布尔标志,告诉提供程序是否使用折叠/展开语义。这样,如果添加配方发生在遍历开始时,应用程序将使用折叠/展开语义;如果不是在开头,则不折叠/展开。虽然很容易把猪的唇膏当作一种解决方法,但我们的应用程序使用的大多数配方都不会出现在遍历的开始。

为了提供一个示例,假设我有三个使用标签vTest和IDs v1 id、v2 id和v3 id的顶点,由Gremlin配方提供程序生成的Gremlin查询将如下所示:

g.V('v1-id')
  .has('partitionKey','v1')
  .fold()
  .coalesce(
    __.unfold(),
    __.addV('vTest')
      .property('id','v1-id')
      .property('partitionKey','v1')
  ).coalesce(
    __.V('v2-id')
      .has('partitionKey','v2'),
    __.addV('vTest')
      .property('id','v2-id')
      .property('partitionKey','v2')
  ).coalesce(
    __.V('v3-id')
      .has('partitionKey','v3'),
    __.addV('vTest')
      .property('id','v3-id')
      .property('partitionKey','v3')
  )
因为查询的每个部分都保证返回一个结果,所以coalesce始终有效。但是,我相信你会同意,猪的唇膏。


不幸的是,我们应用程序中的所有用户注册都将受到折叠/展开方法的影响,因为该过程涉及到创建第一个顶点。我当然希望将来看到对Gremlin的更新,无论是合并还是其他处理条件的步骤。

经过一番挖掘,我意识到问题是特定于Gremlin语言的,而不是特定于服务器实现的,而不是Cosmos DB的问题。因此,我使用了两种addif-not-exists模式

对于上下文,我们使用Gremlin配方提供程序模式,它确保在整个产品中为常见任务维护通用约定。因此,当我有一个要创建的元素边或顶点时,我将其传递给配方提供者,以返回带有addE/addV和生成的属性语义的遍历。这个问题源于生成支持addif-notexists模式的配方

为了解决这个问题,我向配方提供程序传递一个布尔标志,告诉提供程序是否使用折叠/展开语义。这样,如果添加配方发生在遍历开始时,应用程序将使用折叠/展开语义;如果不是在开头,则不折叠/展开。虽然很容易把猪的唇膏当作一种解决方法,但我们的应用程序使用的大多数配方都不会出现在遍历的开始。

为了提供一个示例,假设我有三个使用标签vTest和IDs v1 id、v2 id和v3 id的顶点,由Gremlin配方提供程序生成的Gremlin查询将如下所示:

g.V('v1-id')
  .has('partitionKey','v1')
  .fold()
  .coalesce(
    __.unfold(),
    __.addV('vTest')
      .property('id','v1-id')
      .property('partitionKey','v1')
  ).coalesce(
    __.V('v2-id')
      .has('partitionKey','v2'),
    __.addV('vTest')
      .property('id','v2-id')
      .property('partitionKey','v2')
  ).coalesce(
    __.V('v3-id')
      .has('partitionKey','v3'),
    __.addV('vTest')
      .property('id','v3-id')
      .property('partitionKey','v3')
  )
因为查询的每个部分都保证返回一个结果,所以coalesce始终有效。但是,我相信你会同意,猪的唇膏。


不幸的是,我们应用程序中的所有用户注册都将受到折叠/展开方法的影响,因为该过程涉及到创建第一个顶点。我当然希望在将来看到对Gremlin的更新,无论是合并还是其他处理条件的步骤。

为什么这会如此复杂?我宁愿看到一个小精灵的bug报告,也不愿看到这样的解决方法。为什么这会如此复杂?我宁愿看到一个小精灵bug报告,也不愿看到这样的解决方法。