简体   繁体   中英

How can I refer to an as-variable inside a nested Gremlin traversal?

In trying to write a traversal that matches only if there is not an existing edge from vertex Vo to vertex Vi (where the ID of Vi might not be known ahead of time, and so Vi has to be specified by a traversal).

I had this initial traversal:

<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))
  );
}

My problem is that I can't figure out how to make Vi available inside the nested anonymous traversal; everything I've thought of results in the error

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

I've debugged the call to getScopeValue , and in fact Vi is never defined when I get there.

Approaches I've tried to populate Vi include:

// 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 far as I can tell, this is the result of some scoping rule that detaches the nested anonymous traversals from the scope values; how do I bridge the gap so that an as -variable defined in the upstream part of the traversal can be referenced from inside coalesce-and-where?

Your first version of this is very close to correct, however you didn't specify what Vi represents. You can do this through the use of a mid-traversal V(). Here is how you would accomplish something like this on the modern graph:

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

In this example, I am specifying the vertex id, but you could use other Gremlin filter steps to get the desired result.

This approach seems inefficient and icky, but it does work. I still don't know why I can access a group but not an 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)
  )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM