简体   繁体   English

在Orient-DB中懒惰地执行查询

[英]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 我们开发了一个包含函数的插件

  1. for special traversal this graph to lower reoccurences of similar paths while TRAVERSE execution. 对于特殊遍历该图表,以降低的同时类似路径reoccurences TRAVERSE执行。 We will refer it as search() 我们将其称为search()
  2. for special effective extraction of desired information from results of such traverses. 从这种遍历的结果中特别有效地提取所需信息。 We will refer it as extract() 我们将其称为extract()
  3. for extracting best 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. 这个表格非常理想,因此我们可以根据WHILEWHERE调整条件以适应当前任务。 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步骤,以便在SELECTbest()处理早期路径之后使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM