Merge results from multiple queries in Gremlin
Asked Answered
C

2

5

Let's say I want to get a few vertices from my database:

g.V(1, 2, 3)

And then I have another set of vertices:

g.V(4, 5, 6)

Imagine it's not just g.V(), but some more complicated traversal to get my vertices. But the traversal must start with V(), because I wanna pick from all of my nodes.

Let's also assume I wanna do this multiple times. So I might want to merge 7 different result sets. Each one can have completely different way to get its results.


Now I want to merge these two results into one result set. My first thought was this:

g.V(1, 2, 3).fold().as('x').V(4, 5, 6).fold().as('x').select(all, 'x').unfold()

But this doesn't work. The second call to fold will clear out my "local variables", because it's a barrier step.

My current attempt is this:

g.V(1, 2, 3).fold().union(identity(), V(4, 5, 6).fold()).unfold()

This works, but looks a bit too complicated. If I wanna repeat it 7 times, it'll make for a very complex query.

Is there a better way to accomplish simple merging of results from two different queries?

Clastic answered 28/1, 2020 at 9:25 Comment(0)
A
5

How about using aggregate():

gremlin> g.V(1,2,3).aggregate('x').fold().V(4,5,6).aggregate('x').cap('x')
==>[v[1],v[2],v[3],v[4],v[5],v[6]]
gremlin> g.inject(1).union(V(1,2,3).aggregate('x'),V(4,5,6).aggregate('x')).cap('x')
==>[v[1],v[2],v[3],v[4],v[5],v[6]]

You didn't have a specific traversal in your question so I had to come up with some contrived examples, but the point here is that you can use aggregate() to side-effect the output of specific steps into a List which you can cap() out at the end of your traversal as a result.

Adsorbent answered 28/1, 2020 at 11:37 Comment(2)
This works for me, but it doesn't keep the order in which the queries are submitted if some branches are non-existent (which I mark with a coalesce(__.id(), __.constant(NONE)). Is it possible to get the responses in the order as they were submitted?Jegar
Nevermind, I solved it by using giving each subquery an index and projecting that as a constant: .project("result", "orderNumber").by(__.id(), __constant(orderNumber)) Where orderNumber is the reference on the client side with which to link the result to the original query. I see you answer a lot with "use project" and it solved my problem too :)Jegar
J
4

My suggestion would have been your current approach and, actually, I don't see how this would be any more complicated than any other solution. In fact, I think it stays pretty simple, no matter how many branches you add.

g.V(1, 2, 3).fold().
  union(identity(),
        V(4, 5, 6).fold(),
        V(7, 8, 9).fold(),
        ...).unfold()
Janeljanela answered 29/1, 2020 at 6:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.