或在 Gremlin 中使用 Match 语句的语句

Or statement with Match statement in Gremlin

我有一个具有以下架构的 Janusgraph 数据库:

(期刊)<-[PublishedIn]-(论文)<-[AuthorOf]-(作者)

我正在尝试使用 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()

此查询成功运行,但 returns 0 个顶点和 0 个边。如果我将查询分成两部分并分别搜索每个 Journal displayName,我会得到完整的图表,所以我假设我的查询的 logic/syntax 有问题。

如果我这样写查询:

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()

它 returns 一个有大约 7000 个节点的网络。我怎样才能 re-write 这个查询使用 match() 子句?

我不确定这是否是您的全部问题,但我认为您的 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() 的示例,如 earlier question from you 的不同答案中所述,效果很好:

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()-step 更好,但只有 profile() 的 JanusGraph 会像所讨论的 here 那样告诉我们。

综上所述,我想知道为什么你的 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() 的性能要高得多。