在 Orient-DB 中延迟执行查询

Execute query lazily in Orient-DB

在当前项目中,我们需要在几乎完全连接的图中找到最便宜的路径,每个顶点对可能包含很多边。

我们开发了a plugin包含函数

  1. 对于此图的特殊遍历,可在 TRAVERSE 执行时降低相似路径的重复出现。我们将其称为 search()
  2. 用于从此类遍历的结果中特别有效地提取所需信息。我们将其称为 extract()
  3. 用于根据目标参数提取最佳 N 记录而不需要昂贵的 ORDER BY。我们将其称为 best()

但是结果查询在完整数据上的性能仍然不尽如人意。

因此我们决定修改 search() 函数,以便它可以首先观察最佳边缘并通过使用 best() 函数的当前状态修剪导致绝对不希望的结果的路径。
整体解决方案实际上是 Branch and Bound method

的灵​​活实现

结果查询(省略 extract() 步骤)应该类似于

SELECT best(path, <limit>) FROM (
   TRAVERSE search(<params>) FROM #<starting_point>
   WHILE <conditions on intermediate vertixes>
  ) WHERE <conditions on result elements> 

非常需要这种形式,因此我们可以根据当前任务调整 WHILEWHERE 下的条件。 path 字段由 search() 生成,其中包含 best() 继续进行的所有信息。

问题在于best()函数是严格在search()函数之后执行的,所以search()不能根据best()已经评估的结果修剪非最优分支.

所以问题是:
有没有一种方法可以将 TRAVERSE 步骤的结果管道化到 SELECT 步骤,就像在 SELECT 处理较早的路径之后,旧路径 TRAVERSEd 和 search() best()?

本例中的查询执行将被流式传输。如果您添加

 System.out.println()

或者您在函数中放置一个断点,您将看到调用顺序将是

search
best
search
best
search
...

您可以使用 ThreadLocal 对象 http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html

存储一些上下文数据并在两个函数之间共享,或者您可以使用 OCommandContext(OSQLFunction.execute() 方法中的最后一个参数来存储上下文信息。

您可以为此使用 context.getVariable()context.setVariable()

两个查询(父查询和内部查询)的上下文不同,但它们应该通过 parent/child 关系链接,因此您应该能够使用 OCommandContext.getParent() 检索它们