如何使用Orient 3.0流进行分页

时间:2018-02-07 03:37:40

标签: stream orientdb paging

根据http://orientdb.com/docs/3.0.x/java/Java-Query-API.html的流媒体示例,我们可以使用Orient结果集流API,如下所示

ODatabaseDocument db;
...
String statement = "SELECT FROM V WHERE name = ? and surnanme = ?";
OResultSet rs = db.query(statement, "John", "Smith");
rs.stream().forEach(x -> System.out.println(x.getProperty("age")));
rs.close();

这很好,但太微不足道了 - 如果我们需要保持rs / stream呢?我们无法很好地关闭结果集,因为我们希望在Web应用程序中的后续用户请求上重用该流,例如(在分页等场景中)。

但是为了保持溪流"活着"东方用户指南说:

  

OResultSet实现为一个分页结构,它包含一些   迭代期间迭代器打开。在远程和   在嵌入式使用中。

     

你应该总是在结尾处调用OResultSet.close()   执行,释放资源。

     

关闭时,OResultSet实例会自动关闭   返回它们的ODatabase。

     

始终关闭结果集非常重要,即使结果集也是如此   转换为流(在使用流之后)。

有没有最好的做法。据我所知,我们需要:

1)保持Orient数据库连接打开,直到用户" paging"会话结束(可以说是5-10分钟)。只有当用户说完"完成"我们可以关闭结果集吗?关闭数据库连接。因此,Orient数据库连接(以及它生成的任何流)变为"私有"到单个应用程序用户。此外,由于可以在不同的线程上激活每个用户请求,因此在使用之前需要在当前线程上激活所述数据库连接。

2)使用Java Stream API来浏览"任意"的任意子集。大结果集。底层Orient数据流实现如何处理内存使用?是什么决定了使用"单个rs / stream"并保持一段时间?当我们有数千个开放的rs / stream时会发生什么,特别是如果每​​个用户拥有自己的"私有" rs / stream他们正在看?

3)如果给定的Orient数据库连接一次只能在一个线程上使用(Orient要求),我们如何使用自己的自定义长寿命rs / streams / connections处理多个用户?这是否意味着如果我们有1000个客户端使用他们自己的私有rs /流(他们坚持说5分钟),那么我们必须保持1000个数据库连接打开(即每个用户/ rs一个?)什么是这个限制?这种风格显然与用于快速用户交互的更典型的执行查询/关闭rs模式完全不同,从一个请求到下一个请求是无状态的(对于给定范围每次重新执行查询的天真分页,这可能变得昂贵)< / p>

P.S。我意识到,一旦我们得到一个Java流,那么我们几乎开始只使用Java API本身 - 所以我想,一旦你开始进入Stream接口,JOOQ流使用(例如)将非常类似于Orient流使用 - 我不熟悉Java Streams API,但我认为How to paginate a list of objects in Java 8?是一个很好的起点?

1 个答案:

答案 0 :(得分:0)

我的结论是,当滚动浏览大型结果集而不消耗大量内存或不得不继续重新执行偏移/限制查询时,流式传输效果很好(类似于仅向前滚动JDBC结果集)。典型的用例是导出方案。

对于前向和后向分页,至少在Orient中,您可能需要索引属性/属性并执行范围查询 - 您需要确保索引是SB-tree,以便它支持范围查询。

仅供参考,Solr有一个游标机制,可以很好地对分类结果进行前向分页 - 但是如果你在客户端上保留一些简单的状态标记,你也可以回到已经遇到的结果。 Solr游标不支持“转到”随机页面,但您可以随时对某些其他条件进行重新排序/过滤,以便将“有用”结果移到结果集的顶部而不是深度分页(https://lucene.apache.org/solr/guide/6_6/pagination-of-results.html