7

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

graph.traversal().V(outVertex).bothE(edgeLabel).filter(__.otherV().is(inVertex))

我觉得这filter一步必须遍历所有边缘,这对于一些边缘很多的应用程序来说真的很慢。

另一种方法可能是:

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

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

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

我正在使用 Titan,所以你也可以让你的答案 Titan 具体。

编辑

就时间而言,似乎第一种方法更快(顶点的边缘为 20kb

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

IO怎么样?

4

2 回答 2

11

我希望第一个查询更快。但是,有几件事:

  1. 没有一个查询是最优的,因为它们都支持路径计算。如果您需要在两个方向上查找连接,则使用 2 个查询(我将在下面给出示例)
  2. 使用时clock(),一定要iterate()遍历,否则你只会衡量什么都不做需要多长时间。

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

g.V(a).outE(edgeLabel).filter(inV().is(b))
g.V(b).outE(edgeLabel).filter(inV().is(a))

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

edge = g.V(a).outE(edgeLabel).filter(inV().is(b)).tryNext().orElseGet {
       g.V(b).outE(edgeLabel).filter(inV().is(a)).tryNext()
}

这样你就摆脱了路径计算。这些查询的执行方式很大程度上取决于底层图形数据库。Titan 的查询优化器可以识别该查询模式,并且应该几乎立即返回结果。

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

clock(100) {
  g.V(a).outE(edgeLabel).filter(inV().is(b)).iterate()
  g.V(b).outE(edgeLabel).filter(inV().is(a)).iterate()
}
于 2016-03-12T03:15:54.503 回答
6

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

g.V().has('propertykey','value1').outE('thatlabel').as('e').inV().has('propertykey','value2').select('e')

这也只是单向的,因此需要重新制定相反方向的查询。

于 2016-05-27T08:35:25.577 回答