Given this ultra-simple graph, with unknown number of vertices between A and Z, I can easily check if a specific pattern is satisfied, e.g.
Is there a vertex named "B" eventually followed by "D"?
would be answered by:
boolean matches = g.V().match(
as("b").has("name", "B"),
as("b").repeat(out()).until(has("name", "D")).as("d")
)
.hasNext();
But how would I check if 2 (or more) non-overlapping patterns are satisfied? E.g.
Is there also a vertex named "G" eventually followed by "J"?
I'd naturally do:
boolean matches = g.V().match(
as("b").has("name", "B"),
as("b").repeat(out()).until(has("name", "D")).as("d"),
as("g").has("name", "G"),
as("g").repeat(out()).until(has("name", "J")).as("j")
)
.hasNext();
But this gives me the dreaded The provided match pattern is unsolvable
. Not sure why this would be problematic...
I can of course re-start the traversal from g.V()
and try each match individually, but I'm trying to understand if that would really be necessary and, if so, why.
Union step is what you need.
g.V().
union(
match(
__.as('a').has("name", "marko").as('b'),
__.as('b').repeat(out()).until(has("name", "vadas")).as('c')).
select('a', 'c'),
match(
__.as('d').has("name", "marko").as('e'),
__.as('e').repeat(out()).until(has("name", "ripple")).as('f')).
select('d', 'f')).
unfold().
fold()
You can add as many as matching patterns in the union. Union will run child traversal on incoming V() traversal output.
PS: I ran this query on modern graph as per tinkerpop documentation.