Is it possible in Gremlin to select data from inner steps

I got a case

I need to select node_1, that has some edges, or select just an node_1 by itself

traversal()
        .V().hasLabel("label_1")
        .has("property_key", P.within(numbers)).as("node_1")
        .or(
                __.bothE().hasLabel("label_2").dedup().as("rels").otherV().as("node_2"),
                __.constant(true)
        )
        .project("n1","r", "n2")
        .by(__.select("node_1"))
        .by(__.coalesce(__.unfold().select("rels"), __.unfold()))
        .by(__.coalesce(__.unfold().select("node_2"), __.unfold()))
        .toList()

But in result, when i watch the rels, there is a node_1. And in a node_2, there is also a node_1

You can see:

enter image description here

I guess, it is because gremlin cant find rels and node_2 in step structure

But in graph - such a vertexes and edges present

So if i write same without "or"

traversal()
        .V().hasLabel("label_1")
        .has("property_key", P.within(numbers)).as("node_1")
        .bothE().hasLabel("label_2").dedup().as("rels").otherV().as("node_2")
        .project("n1","r", "n2")
        .by(__.select("node_1"))
        .by(__.select("rels"))
        .by(__.select("node_2"))
        .toList()

I got the result

enter image description here

As you can see

I understand, that in first case, the __.unfold() is triggered, so we got the node_1 everywhere

But how i can get rels or node_2 - i cant understand

Is there any solutions to get steps from or step

Or maybe there is another solutions to find either

"node_1" + "rels" + "node_2"

or to find only

"node_1" + default_value + default_value

using only one query

Thanks for answer!

P.S.

Here is some text for better search in google, i use that queries when i was searching for an answer, get it from browser history:

gremlin select step from or, gremlin select inner step, gremlin select step, gremlin select inner step name, gremlin select multiply step name, gremlin as inside or

Upvotes: 0

Views: 631

Answers (1)

stephen mallette
stephen mallette

Reputation: 46216

There is no path inside of a filter to select() from:

gremlin> g.inject(1,2,3).as('a').or(__.is(1).as('b'),__.is(2).as('c')).path()
==>[1]
==>[2]
gremlin> g.inject(1,2,3).as('a').filter(__.is(1).as('b')).path()
==>[1]

You need to actually have Gremlin traverse a path for it to get added to the history. I'm not sure I follow what you are trying to do, but I think you could simplify the structure of you whole traversal to:

g.V().hasLabel("label_1").
  has("property_key", P.within(numbers)).
  coalesce(bothE("label_2").elementMap(),
           identity())

This way your conditional is handled by coalesce() and each edge gets returned. You can obviously replace elementMap() with something more robust if you need to return data on both vertices - perhaps just replace it with a project() variation.

Upvotes: 1

Related Questions