【问题标题】:Optimizing gremlin query to avoid multiple traversals of graph优化 gremlin 查询以避免图的多次遍历
【发布时间】:2021-01-18 11:56:57
【问题描述】:

我对 Gremlin 查询范式并不陌生。我有以下 gremlin 查询来获取与 foo 类型的节点相关的所有节点。

g.V().hasLabel('foo').as('foo')
.coalesce(out('hasBar'), constant('')).as('bar')
.select('foo').coalesce(out('hasDelta'), constant('')).as('Delta')
.select('foo').coalesce(out('hasBar').out('hasGamma'), constant('')).as('Gamma')
.select('foo', 'bar', 'Delta', 'Gamma')

但这不是优化的,因为我必须多次遍历图表并减慢查询执行速度。

编辑

样本数据 -

g.addV('foo').property('id', '1').property('p1', '1234').property('pk', 1)
g.addV('bar').property('id', '2').property('p2', '12345').property('pk', 1)
g.addV('Gamma').property('id', '3').property('p3', '123').property('pk', 1)
g.addV('Delta').property('id', '4').property('p4', '12').property('pk', 1)
g.V('1').addE("hasBar").to(g.V('2'))
g.V('1').addE("hasGamma").to(g.V('3'))
g.V('2').addE("hasDelta").to(g.V('4'))
g.addV('foo').property('id', '5').property('p1', '12345').property('pk', 1)
g.V('5').addE("hasBar").to(g.V('2'))
g.V('5').addE("hasGamma").to(g.V('3'))
g.addV('foo').property('id', '6').property('p1', '1').property('pk', 1)
g.V('6').addE("hasBar").to(g.V('2'))
g.V('6').addE("hasGamma").to(g.V('3'))
g.addV('foo').property('id', '7').property('p1', '145').property('pk', 1)
g.V('7').addE("hasBar").to(g.V('2'))
g.V('7').addE("hasGamma").to(g.V('3'))
g.addV('foo').property('id', '8').property('p1', '15').property('pk', 1)
g.addV('bar').property('id', '9').property('p2', '78').property('pk', 1)
g.addV('Gamma').property('id', '10').property('p3', '1236').property('pk', 1)
g.addV('Delta').property('id', '11').property('p4', '1258').property('pk', 1)
g.V('8').addE("hasBar").to(g.V('9'))
g.V('8').addE("hasGamma").to(g.V('10'))
g.V('10').addE("hasDelta").to(g.V('11'))

之前我是获取所有的 foo 然后查询对应的 bar、gamma 和 delta,效率非常低,所以将查询更改为一次获取​​,但现在我在做同样的事情,但避免了网络调用。

以上查询给出以下响应-

[
{
    foo: {},
    bar: {},
    Delta: {},
    Gamma: {}
},
{
    foo: {},
    bar: {},
    Delta: {},
    Gamma: {}
}
]

【问题讨论】:

    标签: gremlin graph-databases


    【解决方案1】:

    您可以利用标签并使用path 步骤:

    g.V().hasLabel('foo').
          outE('hasBar','hasDelta','hasGamma').
          inV().
          path().by(label)
    

    如果您想通过属性或其 ID 来识别顶点,则在 path 步骤之后添加第二个 by 调制器即可。

    g.V().hasLabel('foo').
          outE('hasBar','hasDelta','hasGamma').
          inV().
          path().
            by(id).
            by(label)
    

    返回的路径将采用以下形式(我只是假设数字 ID):

    [1,hasBar,10]
    [1,hasDelta,15]
    [1,hasGamma,27]
    

    【讨论】:

    • 有一个问题,hasGamma 是从 bar 到 Gamma 的边缘,即 foo->bar->gamma。
    • 您能否添加一组 Gremlin 步骤来创建示例图?最初的问题并不清楚这种细微差别。但是,我描述的方式仍然可以使用path。您可能只需要添加一个repeat 步骤。
    • 感谢 Kelvin,我已经添加了示例数据。让我试试建议
    最近更新 更多