【问题标题】:How can I refer to an as-variable inside a nested Gremlin traversal?如何在嵌套的 Gremlin 遍历中引用 as-variable?
【发布时间】:2021-02-02 01:39:22
【问题描述】:

在尝试编写仅在从顶点 Vo 到顶点 Vi 不存在边时才匹配的遍历(其中 Vi 的 ID 可能无法提前知道,因此必须通过遍历指定 Vi) .

我有这个初始遍历:

<A> GraphTraversal<A, Edge> addEdge(
  GraphTraversal<A, Vertex> traversalToVo,
  String viSelectKey
) {
  return traversalToVo.coalesce(
    __.outE("Manages").and(
      __.inV().as("inV").where("inV", P.neq(viSelectKey))
      // more conditions
    ),
    __addE("Manages").to(select(viSelectKey))
  );
}

我的问题是我不知道如何使Vi 在嵌套匿名遍历中可用;我想到的一切都会导致错误

Neither the sideEffects, map, nor path has a Vi-key: WherePredicateStep(inV,neq(Vi))

我已经调试了对getScopeValue 的调用,事实上,当我到达那里时,从未定义过Vi

我尝试填充 Vi 的方法包括:

// define "Vi" in the upstream part of the query
gts.addV(...).as("Vi").V(Vo).coalesce(...)

// modeled after "Long Traversals" recipe; variable not defined afterward
gt.V(Vo).sideEffect(viTraversal.asAdmin().clone().as("Vi")).coalesce(...)

// produces a Map, and I can't apply unfold() downstream inside predicate
gt.sideEffect(viTraversal.asAdmin().clone().group("Vi"))

据我所知,这是一些将嵌套匿名遍历与范围值分离的范围规则的结果;如何弥合差距,以便可以从内部合并和何处引用遍历上游部分中定义的as-variable?

【问题讨论】:

标签: java gremlin tinkerpop3


【解决方案1】:

您的第一个版本非常接近正确,但是您没有指定 Vi 代表什么。您可以通过使用中间遍历 V() 来做到这一点。以下是您将如何在现代图表上完成这样的事情:

g.V(2).as('Vi').V(1).coalesce(
  __.outE("Manages").and(
    __.inV().where(P.neq("Vi"))
  ),
  __.addE("Manages").to(select("Vi"))
);

在本例中,我指定了顶点 ID,但您可以使用其他 Gremlin 过滤器步骤来获得所需的结果。

【讨论】:

  • 第一个版本确实指定ViaddVVi 键在谓词范围内不可用。
  • 我的答案基于的第一个版本中没有 Vi 或 addV(),所以我不太确定您指的是什么。具有 addV 的那个没有显示足够的查询来理解可能是什么问题。我在答案中输入的遍历经过测试可以针对 Gremlin Server。
  • 我会澄清的,谢谢。它可以与 TinkerGraph 一起使用吗?
  • 是的,我已经在 Gremlin 控制台中针对 TInkerGraph 进行了测试
【解决方案2】:

这种方法似乎效率低下且令人讨厌,但确实有效。我仍然不知道为什么我可以访问 group 而不是 as

traversalToVo.sideEffect(traversalToVi.asAdmin().clone().group("toV").by(id))
  .coalesce(
    __.outE("rel").and(
      __.inV().id().where(P.within("toV")).by().by(Column.keys),
      // other filters
    ),
    __.addE("rel").to(traversalToVi)
  )

【讨论】:

  • 我对这里的问题和 sideEffect() 的使用感到困惑。当您像这样运行遍历时,它会起作用:g.V(Vi).as('Vi').V(Vo).both().select('Vi')
  • @bechbd 那个 是的。什么不起作用是在合并中使用select('Vi')->and.
  • 我想我不明白这里的问题。我在上一个答案中提供了一个工作示例,该示例已使用 Gremlin 控制台中的“现代”图表针对 TinkerGraph 进行了测试。它与原始查询的语法相同,但添加了指定“Vi”。您的原始查询从未使用 'as('Vi')' 指定任何内容,因此无法选择('Vi')。如果我有误解,请将整个查询(包括缺少的 traversalToVo 部分)放入原始帖子中。谢谢。
  • @bechbd 自编失明;我经历了足够多的修改,我没有意识到问题中缺少的上下文。更新中。
  • 没问题。但是,您的原始查询的问题似乎仍然是该查询的任何部分都没有显示您将任何内容设置为“Vi”的别名。例如g.V().limit(1).as('Vi') 。您正在从参数中传递键,但是在查询的第一部分中设置的是什么。如果没有这个,我的猜测是 traversalToVo 正在使用减少障碍步骤(例如 fold()、max()、min()、group() 等),这会阻止您在遍历后期使用任何别名,因为它无法知道别名指的是什么。
猜你喜欢
  • 2016-08-08
  • 2020-04-09
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2018-07-12
  • 2010-12-06
  • 2021-02-27
相关资源
最近更新 更多