比选择/分支/合并更好的解决方案

时间:2019-07-01 13:04:38

标签: gremlin

我正在尝试在gremlin中实现Ldbc SNB IC5。现在,我得到了以下DSL:

g.E().
hasLabel('hasMember').has('joinDate', gt(1292457600000)).
fold().
sideEffect(g.V().has('p.id', 4398046514041).    
    repeat(both('knows').simplePath()).
    emit().times(2).dedup().aggregate('friend')).
unfold().as('candidate').
inV().where(within('friend')).as('person').
select('candidate').outV().as('forum').
out('containerOf').hasLabel('post').out('hasCreator').as('creator').
where(eq('person')).count(local).
as('cnt').select('forum', 'person', 'cnt')

哪个产生结果:

==>[forum:v[f17179878665],person:v[p2199023257492],cnt:1]
==>[forum:v[f34359749233],person:v[p3298534884212],cnt:1]
==>[forum:v[f8589934681],person:v[p4398046511765],cnt:1]
==>[forum:v[f17179880026],person:v[p1099511630430],cnt:1]
==>[forum:v[f34359740386],person:v[p2370],cnt:1]
==>[forum:v[f25769814145],person:v[p5497558139737],cnt:1]

结果非常接近,但不完全是我想要的结果,我需要空条目的记录,其中cnt0
直观的方法是使用choose

g.E().
hasLabel('hasMember').has('joinDate', gt(1292457600000)).
fold().
sideEffect(g.V().has('p.id', 4398046514041).    
    repeat(both('knows').simplePath()).
    emit().times(2).dedup().aggregate('friend')).
unfold().as('candidate').
inV().where(within('friend')).as('person').
select('candidate').outV().as('forum').
out('containerOf').hasLabel('post').out('hasCreator').as('creator').
choose(
  where(eq('person')), 
    constant(1), 
    constant(0)).
as('cnt').select('forum', 'person', 'cnt')

不幸的是,该查询超时在默认超时30s之后。然后,我强制设置limit来查看profile的结果:

gremlin> g.E().
......1> hasLabel('hasMember').has('joinDate', gt(1292457600000)).
......2> fold().
......3> sideEffect(g.V().has('p.id', 4398046514041).
......4>   repeat(both('knows').simplePath()).
......5>   emit().times(2).dedup().aggregate('friend')).
......6> unfold().as('candidate').
......7> inV().where(within('friend')).as('person').
......8> select('candidate').outV().as('forum').
......9> out('containerOf').hasLabel('post').out('hasCreator').as('creator').
.....10> limit(100).
.....11> choose(
.....12>   where(eq('person')),
.....13>   constant(1),
.....14>   constant(0)).
.....15> as('cnt').select('forum', 'person', 'cnt').profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
GraphDbGraphStep(edge,[~label.eq(hasMember), jo...                 29704       29704         559.852    50.95
FoldStep                                                               1           1          15.712     1.43
TraversalSideEffectStep([ParallelStep([GraphDbG...                     1           1          25.613     2.33
  ParallelStep([GraphDbGraphStep(vertex,p.id.eq...                     2           2          10.947
  RepeatStep([VertexStep(BOTH,[knows],vertex), ...                   692         692           5.613
    VertexStep(BOTH,[knows],vertex)                                  696         696           3.714
    PathFilterStep(simple)                                           692         692           0.736
    RepeatEndStep                                                    692         692           0.634
  DedupGlobalStep                                                    330         330           0.542
  AggregateStep(friend)                                              330         330           0.659
UnfoldStep@[candidate]                                                84          84           0.202     0.02
EdgeVertexStep(IN)                                                    84          84           0.130     0.01
WherePredicateStep(within([friend]))@[person]                         18          18           0.086     0.01
SelectOneStep(last,candidate)                                         18          18           0.038     0.00
EdgeVertexStep(OUT)@[forum]                                           18          18           0.037     0.00
VertexStep(OUT,[containerOf],vertex)                                 101         101           1.748     0.16
HasStep([~label.eq(post)])                                           101         101           0.163     0.01
VertexStep(OUT,[hasCreator],vertex)@[creator]                        101         101           8.613     0.78
RangeGlobalStep(0,100)                                               100         100           0.232     0.02
ChooseStep([WherePredicateStep(eq(person)), Pro...                   100         100         485.889    44.22
  WherePredicateStep(eq(person))                                                              80.862
  HasNextStep                                                        100         100           0.324
  ConstantStep(0)                                                    100         100           0.365
  EndStep                                                            100         100           0.295
SelectStep(last,[forum, person, cnt])                                100         100           0.571     0.05
                                            >TOTAL                     -           -        1098.892        -

profile的结果表明,choose步骤花费的时间比我预期的要多得多。
然后我尝试了branch/coalesce,它花费的时间与choose相同。

所以我的问题是,是否可以使用除choose/branch/coalesce以外的更好的步骤。

我的数据库规模如下:

gremlin> g.V().count()
==>92118
gremlin> g.E().count()
==>335131

0 个答案:

没有答案