如何使用Gremlin提高最短路径的性能?

时间:2018-05-08 17:58:22

标签: graph cassandra shortest-path gremlin janusgraph

我使用带有Gremlin的JanusGraph和this数据集,其中包含2.6k节点和6.6k边缘(两侧3.3k边缘)。我在没有找到最短路径的情况下运行查询10分钟。

使用Gephi,最短路径几乎是即时的。

这是我的疑问:

g.V(687).repeat(out().simplePath()).until(hasId(1343)).path().limit(1)

1 个答案:

答案 0 :(得分:4)

使用simplePath(),您的查询仍会处理比必要更多的路径。例如,如果688687的直接邻居,但也是1000的邻居,在另一条路径上距离是10跳,那么您为什么要遵循{1000的路径{1}}到688,如果您早已见过这个十字路口?

所以,你应该过滤掉你之前见过的任何十字路口(第一次出现总是最接近的):

g.V(687).store('x').
  repeat(out().where(without('x')).aggregate('x')).
   until(hasId(1343)).limit(1).path()

另请注意,我换了limit(1)path;这是因为先浪费资源(CPU和内存)来收集所有路径,然后再拿第一个路径。

<强>更新

如果其他人想尝试一下,这里有将数据集加载到TinkerGraph的代码:

g = TinkerGraph.open().traversal()
"http://nrvis.com/download/data/road/road-minnesota.zip".toURL().withInputStream {
  new java.util.zip.ZipInputStream(it).with {
    while (entry = it.getNextEntry()) {
      if ("road-minnesota.mtx" == entry.getName()) {
        it.eachLine {
          if (it ==~ /[0-9]+ [0-9]+/) {
            def (a, b) = it.split()*.toInteger()
            g.V(a).fold().
              coalesce(unfold(), addV().property(id, a)).
              addE("road").
                to(V(b).fold().coalesce(unfold(), addV().property(id, b))).inV().
              addE("road").to(V(a)).iterate()
          }
        }
        break
      }
      it.closeEntry()
    }
  }
}

查询和一点基准:

gremlin> g.V(687).store('x').
......1>   repeat(out().where(without('x')).aggregate('x')).
......2>    until(hasId(1343)).limit(1).
......3>   path().by(id)
==>[687,689,686,677,676,675,673,626,610,606,607,608,735,732,733,730,729,734,737,738,739,742,786,816,840,829,815,825,865,895,872,874,968,983,1009,1044,1140,1142,1148,1219,1255,1329,1337,1339,1348,1343]

gremlin> clock (100) {
......1>   g.V(687).store('x').
......2>     repeat(out().where(without('x')).aggregate('x')).
......3>      until(hasId(1343)).limit(1).
......4>     path().iterate()
......5> }
==>12.5362714
TinkerGraph上的12.5毫秒看起来对我很好。期待它在JG上运行一点点,但肯定不会超过10分钟。