#gremlin #tinkerpop3 #tinkerpop
Вопрос:
Учитывая этот ультрапростой график, с неизвестным числом вершин между A и Z, я могу легко проверить, выполняется ли определенный шаблон, например
Существует ли вершина с именем «B», за которой в конечном итоге следует «D»?
будет дан ответ на:
boolean matches = g.V().match(
as("b").has("name", "B"),
as("b").repeat(out()).until(has("name", "D")).as("d")
)
.hasNext();
Но как бы я проверил, выполняются ли 2 (или более) неперекрывающиеся шаблоны? Например.
Существует ли также вершина с именем «G», за которой в конечном итоге следует «J»?
Я бы, естественно, сделал:
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();
Но это наводит на меня ужас The provided match pattern is unsolvable
. Не знаю, почему это было бы проблематично…
Я, конечно, могу заново начать обход g.V()
и попробовать каждый матч по отдельности, но я пытаюсь понять, действительно ли это необходимо и, если да, то почему.
Ответ №1:
Добавление другого ответа просто для того, чтобы показать, что match
в подобных случаях шаг на самом деле не нужен:
gremlin> g.V().has('name','marko').as('a').
......1> union(
......2> repeat(out()).until(has("name", "vadas")).as('c').
......3> select('a', 'c'),
......4> repeat(out()).until(has("name", "ripple")).as('f').
......5> select('a', 'f')
......6> ).
......7> unfold().
......8> fold()
==>[a=v[1],c=v[2],a=v[1],f=v[5]]
Комментарии:
1. Пожалуйста, посмотрите мой комментарий к другому ответу. Я не получу никаких результатов, если все шаблоны не будут удовлетворены, поэтому я не думаю
union
, что это то, что мне нужно.
Ответ №2:
Этот шаг-то, что вам нужно.
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()
Вы можете добавить столько же совпадающих шаблонов в объединение.
Объединение выполнит дочерний обход при входящем выходе обхода V ().
PS: Я выполнил этот запрос на современном графике в соответствии с документацией tinkerpop.
Комментарии:
1. Я только что понял, что это даст мне результат, даже если соответствует только один шаблон, например, если «марко» действительно связан с «вадами», но не с «рябью». В моем случае это неправильно. Не должно быть никакого результата, если все шаблоны не будут удовлетворены.
2. Изменение
union
наand
может быть тем, что вам тогда нужно.