在 Orient-DB 中延迟执行查询
Execute query lazily in Orient-DB
在当前项目中,我们需要在几乎完全连接的图中找到最便宜的路径,每个顶点对可能包含很多边。
我们开发了a plugin包含函数
- 对于此图的特殊遍历,可在
TRAVERSE
执行时降低相似路径的重复出现。我们将其称为 search()
- 用于从此类遍历的结果中特别有效地提取所需信息。我们将其称为
extract()
- 用于根据目标参数提取最佳
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>
非常需要这种形式,因此我们可以根据当前任务调整 WHILE
和 WHERE
下的条件。 path
字段由 search()
生成,其中包含 best()
继续进行的所有信息。
问题在于best()
函数是严格在search()
函数之后执行的,所以search()
不能根据best()
已经评估的结果修剪非最优分支.
所以问题是:
有没有一种方法可以将 TRAVERSE
步骤的结果管道化到 SELECT
步骤,就像在 SELECT
处理较早的路径之后,旧路径 TRAVERSE
d 和 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()
检索它们
在当前项目中,我们需要在几乎完全连接的图中找到最便宜的路径,每个顶点对可能包含很多边。
我们开发了a plugin包含函数
- 对于此图的特殊遍历,可在
TRAVERSE
执行时降低相似路径的重复出现。我们将其称为search()
- 用于从此类遍历的结果中特别有效地提取所需信息。我们将其称为
extract()
- 用于根据目标参数提取最佳
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>
非常需要这种形式,因此我们可以根据当前任务调整 WHILE
和 WHERE
下的条件。 path
字段由 search()
生成,其中包含 best()
继续进行的所有信息。
问题在于best()
函数是严格在search()
函数之后执行的,所以search()
不能根据best()
已经评估的结果修剪非最优分支.
所以问题是:
有没有一种方法可以将 TRAVERSE
步骤的结果管道化到 SELECT
步骤,就像在 SELECT
处理较早的路径之后,旧路径 TRAVERSE
d 和 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()
检索它们