【问题标题】:Combine two gremlin queries with individual start steps into one将两个带有单独启动步骤的 gremlin 查询合并为一个
【发布时间】:2023-02-10 03:23:45
【问题描述】:

我有两个 gremlin 查询,都有单独的启动步骤。我无法控制它们的内部结构(它们作为方法参数传递给我)。我的任务是将它们组合成一个遍历。所以基本上我需要实现这个:

public GraphTraversal<*,*> createUnion(
    GraphTraversal<*, *> t1, 
    GraphTraversal<*,*> t2
){
   // how?
}

我们必须假设:

  • t1 和t2 都有单独的启动步骤 (.V() / .E())
  • 如果t1以.V()开头,t2可能以E()开头,反之亦然。

我尝试了 gremlin union 步骤(它确实接受子遍历),但以下(虽然在语法上有效)不起作用:

t1.union(
    __.identity(),
   t2
)

...因为 union gremlin 中的步骤将始终被评估每个输入元素的 t1。显然,这不是我们想要的。

我还尝试了inject(...) 步骤:

t1.inject(t2.toList().toArray(new Object[0]))

这有两个问题:

  1. t2 在构造查询期间被热切地评估
  2. t2 中定义的任何标签、副作用等在生成的遍历中将不可用。

    有没有更好的方法来做到这一点?理想情况下,一种保留t1 和t2 中的标签并保留惰性求值的方法?

【问题讨论】:

    标签: gremlin graph-databases tinkerpop tinkerpop3


    【解决方案1】:

    我们经常看到将 union() 作为开始步骤的案例,但尚未实现。您可以使用 inject() 和一次性遍历器来解决此问题:

    gremlin> t1 = __.V().has('person','name','josh');[]
    gremlin> t2 = __.V().has('person','name','peter');[]
    gremlin> g.inject(0).union(t1, t2)
    ==>v[4]
    ==>v[6]
    

    哑元或“0”仅用于开始遍历,然后在 union() 处被忽略,因为子遍历从中间遍历 V() 开始。

    请注意确保使用此模式的遍历实际上会优化执行。 explain()/profile() 应该会提示您了解潜在的行为。

    【讨论】:

      猜你喜欢
      • 2014-06-08
      • 2019-07-25
      • 1970-01-01
      • 2021-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多