Amazon Neptune MemoryLimitExceeded在一个有周期的小数据集上



我在一个小数据库上查询~10k条边和~2k个顶点

g.V("{}").repeat(outE().inV()).until(hasId(eq("{}")))

虽然这个查询有点蛮力,但是对于这么小的数据集,我希望它能很快获取。实际上它的结果是

Query cannot be completed due to memory limitations

这在这么小的数据集上是预期的吗?

图中的循环是很常见的,绝不应该总是被认为是错误。考虑A和B是朋友,B和A也是朋友的情况。

我们可以将其建模为:

(A)-FRIEND->(B)-FRIEND->(A)

这是一个完全合理的设计,因为我们可能想要考虑这样的情况,即a声称是B的朋友,但B还没有承认他们确实是a的朋友,所以,我们在每个方向上都有优势。然而,我们现在的数据中有一个循环。

上面描述的示例图可以使用以下命令创建:
g.addV('A').as('a').
  addV('B').as('b').
  addE('FRIEND').from('a').to('b').
  addE('FRIEND').from('b').to('a')  

以你的例子为例,我们可能会想写这样的查询:

g.V().hasLabel('A').repeat(out()).until(hasId('X'))  

然而,给定图中的循环,这本质上是一个无限循环,因为我们将不断访问A,B,A,B等,永远不会找到ID为X的顶点。

我们可以观察到&;无限循环&;使用timeLimit步骤来中断查询,以阻止查询完全运行。

gremlin> g.V().hasLabel('A').repeat(timeLimit(1).out()).until(hasId('X')).emit()
==>v[1]
==>v[0]
==>v[1]
==>v[0]
==>v[1]
==>v[0]
==>v[1]
==>v[0]
==>v[1]
==>v[0]
==>v[1]
==>v[0]
==>v[1]
==>v[0]
==>v[1]  

可以看到,查询被困在一个紧循环中。V[0]为A, V[1]为b,查询因时间限制而终止。

因此,我们需要编写查询代码来处理这些情况。执行此操作的两种最常见的方法是使用simplePathcyclicPath,这取决于您是想捕获循环还是只是过滤掉包含循环的任何结果。

// No results as simplePath stops the traversal as soon as a cycle is found
gremlin> g.V().hasLabel('A').repeat(out().simplePath()).until(hasId('X')).path().by(label)
// We get a result as we stop after finding the cycle but include it in the results
g.V().hasLabel('A').repeat(out()).until(hasId('X').or().cyclicPath()).path().by(label)
==>[A,B,A]  

最新更新