[英]Execute query lazily in Orient-DB
In current project we need to find cheapest paths in almost fully connected graph which can contain lots of edges per vertex pair. 在当前项目中,我们需要在几乎完全连通的图中找到最便宜的路径,每个顶点对可以包含许多边。
We developed a plugin containing functions 我们开发了一个包含函数的插件
TRAVERSE
execution. TRAVERSE
执行。 We will refer it as search()
search()
extract()
extract()
N
records according to target parameter without costly ORDER BY
. N
记录而无需昂贵的ORDER BY
。 We will refer it as best()
best()
But resulted query still has unsatisfactory performance on full data. 但结果查询仍然在完整数据上表现不理想。
So we decided to modify search()
function so it could watch best edges first and prune paths leading to definitely undesired result by using current state of best()
function. 因此我们决定修改
search()
函数,以便它可以首先观察最佳边缘,并通过使用best()
函数的当前状态来修剪导致绝对不希望的结果的路径。
Overall solution is effectively a flexible implementation of Branch and Bound method 整体解决方案实际上是分支定界方法的灵活实现
Resulting query (omitting extract()
step) should look like 结果查询(省略
extract()
步骤)应如下所示
SELECT best(path, <limit>) FROM (
TRAVERSE search(<params>) FROM #<starting_point>
WHILE <conditions on intermediate vertixes>
) WHERE <conditions on result elements>
This form is very desired so we could adapt conditions under WHILE
and WHERE
for our current task. 这个表格非常理想,因此我们可以根据
WHILE
和WHERE
调整条件以适应当前任务。 The path
field is generated by search()
containing all information for best()
to proceed. path
字段由search()
生成,其中包含要继续执行的best()
所有信息。
The trouble is that best()
function is executed strictly after search()
function, so search()
can not prune non-optimal branches according to results already evaluated by best()
. 问题是在
search()
函数之后严格执行best()
函数,因此search()
不能根据best()
已经评估的结果修剪非最佳分支。
So the Question is: 所以问题是:
Is there a way to pipeline results from TRAVERSE
step to SELECT
step in the way that older paths were TRAVERSE
d with search()
after earlier paths handled by SELECT
with best()
? 是否有一种方法可以将结果从
TRAVERSE
步骤转换为SELECT
步骤,以便在SELECT
和best()
处理早期路径之后使用search()
将旧路径转换为TRAVERSE
?
the query execution in this case will be streamed. 在这种情况下,查询执行将被流式传输。 If you add a
如果你添加一个
System.out.println()
or you put a breakpoint in your functions you'll see that the invocation sequence will be 或者在函数中放置断点,您将看到调用序列
search
best
search
best
search
...
You can use a ThreadLocal object http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html 您可以使用ThreadLocal对象http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html
to store some context data and share it between the two functions, or you can use the OCommandContext (the last parameter in OSQLFunction.execute()
method to store context information. 存储一些上下文数据并在两个函数之间共享,或者您可以使用OCommandContext(
OSQLFunction.execute()
方法中的最后一个参数来存储上下文信息。
You can use context.getVariable()
and context.setVariable()
for this. 您可以使用
context.getVariable()
和context.setVariable()
。
The contexts of the two queries (the parent and the inner query) are different, but they should be linked by a parent/child relationship, so you should be able to retrieve them using OCommandContext.getParent()
两个查询(父查询和内部查询)的上下文不同,但它们应该通过父/子关系链接,因此您应该能够使用
OCommandContext.getParent()
来检索它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.