Проверьте, соответствует ли график двум неперекрывающимся шаблонам

#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 может быть тем, что вам тогда нужно.