Gremlin:在两个顶点之间找到边缘的有效方法是什么?

Moh*_*aie 4 gremlin titan tinkerpop3

很明显,在两个顶点之间找到边缘的直接方法是:

graph.traversal().V(outVertex).bothE(edgeLabel).filter(__.otherV().is(inVertex))
Run Code Online (Sandbox Code Playgroud)

我觉得这个filter步骤必须遍历所有边缘,这对于一些有很多边缘的应用来说非常慢.

另一种方式可能是:

traversal = graph.traversal()
                  .V(outVertex)
                  .bothE(edgeLabel)
                  .as("x")
                  .otherV()
                  .is(outVertex) // uses index?
                  .select("x");
Run Code Online (Sandbox Code Playgroud)

我假设第二种方法可能会快得多,因为它将使用ID索引,这将使它比第一种方法更快.

哪一个更快更有效(就IO而言)?

我正在使用泰坦,所以你也可以让你的答案泰坦具体.

编辑

在时间方面,似乎第一种方法更快(边缘为顶点20k b

gremlin> clock(100000){g.V(b).bothE().filter(otherV().is(a))}
==>0.0016451789999999999
gremlin> clock(100000){g.V(b).bothE().as("x").otherV().is(a).select("x")}
==>0.0018231140399999999
Run Code Online (Sandbox Code Playgroud)

IO怎么样?

Dan*_*itz 6

我希望第一个查询更快.但是,很少有事情:

  1. 没有一个查询是最佳的,因为它们都启用了路径计算.如果您需要在两个方向上找到连接,请使用2个查询(我将在下面给出一个示例)
  2. 当你使用时clock(),请确保iterate()你的遍历,否则你只会测量什么都不做的时间.

这些是我用来在两个方向上找到边缘的查询:

g.V(a).outE(edgeLabel).filter(inV().is(b))
g.V(b).outE(edgeLabel).filter(inV().is(a))
Run Code Online (Sandbox Code Playgroud)

如果您希望获得最多一个优势:

edge = g.V(a).outE(edgeLabel).filter(inV().is(b)).tryNext().orElseGet {
       g.V(b).outE(edgeLabel).filter(inV().is(a)).tryNext()
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以摆脱路径计算.这些查询的执行方式在很大程度上取决于底层的图形数据库.Titan的查询优化器识别出查询模式,并且几乎没有时间返回结果.

现在,如果要测量运行时,请执行以下操作:

clock(100) {
  g.V(a).outE(edgeLabel).filter(inV().is(b)).iterate()
  g.V(b).outE(edgeLabel).filter(inV().is(a)).iterate()
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ius 5

如果不知道顶点ID,则另一种解决方案可能是

g.V().has('propertykey','value1').outE('thatlabel').as('e').inV().has('propertykey','value2').select('e')
Run Code Online (Sandbox Code Playgroud)

这也是单向的,因此需要为相反的方向重新构造查询。