Или заявление с оператором матча в Гремлин - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть база данных Janusgraph со следующей схемой:

(журнал) <- [Опубликованный в] - (статья) <- [AuthorOf] - (Автор) </p>

Я пытаюсь написать запрос, используя предложение gremlin match(), которое будет искать два разных журнала и соответствующие статьи с ключевым словом в названии и авторах. Вот что у меня есть:

sg = g.V().match(
    __.as('a').has('Journal', 'displayName', textContains('Journal Name 1')),
    __.as('a').has('Journal', 'displayName', textContains('Journal Name 2')),
    __.as('a').inE('PublishedIn').subgraph('sg').outV().as('b'), 
    __.as('b').has('Paper', 'paperTitle', textContains('My Key word')),
    __.as('b').inE('AuthorOf').subgraph('sg').outV().as('c')).
 cap('sg').next()

Этот запрос успешно выполняется, но возвращает 0 вершин и 0 ребер. Если я разделю запрос на два и выполню поиск каждого displayName журнала отдельно, я получу полные графики, поэтому я предполагаю, что с логикой / синтаксисом моего запроса что-то не так.

Если я напишу запрос следующим образом:

sg = g.V().or(has('JournalFixed', 'displayName', textContains('Journal Name 1')),
              has('JournalFixed', 'displayName', textContains('Journal Name 2'))).
              inE('PublishedInFixed').subgraph('sg').
              outV().has('Paper', 'paperTitle', textContains('My Key word')).
              inE('AuthorOf').subgraph('sg').
              outV().
              cap('sg').
              next()

Возвращает сеть с около 7000 узлов. Как я могу переписать этот запрос, чтобы использовать предложение match()?

1 Ответ

2 голосов
/ 30 апреля 2020

Я не уверен, что это все из-за вашей проблемы, но я думаю, что ваш match() моделирует ваши шаги "displayName", чтобы они были and(), а не or(). Вы можете проверить с помощью profile(), как я сделал здесь с TinkerGraph:

gremlin> g.V().match(__.as('a').has('name','marko'), __.as('a').has('name','josh')).profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
TinkerGraphStep(vertex,[name.eq(marko), name.eq...                                             0.067   100.00
                                            >TOTAL                     -           -           0.067        -

Вы можете решить эту проблему несколькими способами, я полагаю. В моем примере использование within(), как описано в другом ответе на предыдущий вопрос от вас , прекрасно работает:

gremlin> g.V().match(__.as('a').has('name', within('marko','josh'))).profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
TinkerGraphStep(vertex,[name.within([marko, jos...                     2           2           0.098   100.00
                                            >TOTAL                     -           -           0.098        -

В вашем случае я бы заменил:

or(has('JournalFixed', 'displayName', textContains('Journal Name 1')),
   has('JournalFixed', 'displayName', textContains('Journal Name 2')))

с:

has('JournalFixed', 'displayName', textContains('Journal Name 1').
                                   or(textContains('Journal Name 2'))

с преимущественным использованием P.or(). Я думаю, что любой из этих вариантов должен быть лучше, чем использовать or() -этап, но только profile() от JanusGraph сообщит, как обсуждалось здесь .

Все, что сказал, я бы удивился, почему ваш or() не может быть переведен непосредственно в match() следующим образом:

g.V().match(
    __.as('a').or(has('Journal', 'displayName', textContains('Journal Name 1')),
                  has('Journal', 'displayName', textContains('Journal Name 2'))),
    __.as('a').inE('PublishedIn').subgraph('sg').outV().as('b'), 
    __.as('b').has('Paper', 'paperTitle', textContains('My Key word')),
    __.as('b').inE('AuthorOf').subgraph('sg').outV().as('c')).
 cap('sg')

Я бы даже подумал, что мое предложение о P.or() значительно более производительный.

...