使用 Hibernate Search 查询并获取所有项目而无需分页

Posted

技术标签:

【中文标题】使用 Hibernate Search 查询并获取所有项目而无需分页【英文标题】:Query with Hibernate Search and get all items without paging 【发布时间】:2020-07-14 00:50:18 【问题描述】:

我在我的 Spring Boot 项目中使用 Hibernate Search。 大多数情况下,它是满足我需求的完美解决方案,除非有一种情况是我必须通过全文搜索查询选择所有项目。

在使用 Hibernate Search 时是否有机会避免 Hibernate Search / Lucene 分页?类似于Pageable.unpaged() 的东西? 我不想将页面大小设置为Integer.MAX_VALUE,因为它是一种黑客行为。 但是如果没有更好的解决方案,我将不得不这样使用它。

【问题讨论】:

【参考方案1】:

您通常不应该在一个请求中获取所有命中,因为可能有数百万个命中并且全部加载它们可能会导致内存问题。

如果您真的想这样做,您可以简单地通过不对查询设置限制来获取所有结果:

休眠搜索 5:

Session session = /* ... */;
FullTextSession fullTextSession = Search.getFullTextSession( session );
Query luceneQuery = /* ... */;
FullTextQuery ftQuery = fullTextSession.createFullTextQuery( luceneQuery, MyEntity.class );
List<MyEntity> hits = ftQuery.list();

休眠搜索 6:

Session session = /* ... */;
List<MyEntity> = Search.session( session ).search( MyEntity.class )
        .where( f -> /* ... */ )
        .fetchAllHits();

但是在很多情况下它不起作用或者会因为命中占用太多内存而表现不佳。

理想情况下,you should use scrolling instead。

以下是 Hibernate Search 5 的示例:

FullTextQuery ftQuery = /*...*/;
ScrollableResults scroll = ftQuery.scroll();
scroll.beforeFirst();
int i = 0;
while ( scroll.next() ) 
    ++i;
    MyEntity entity = scroll.get()[0];

    // ... do things with the entity ...

    // Flush/clear the session periodically to free memory
    if ( i % 100 == 0 ) 
        // Only necessary if you changed entities
        session.flush();
        // Only necessary if you changed indexed entities
        fullTextSession.flushToIndexes();

        session.clear();
    


对于 Hibernate Search 6,API 会有所不同。它目前正在实施 (HSEARCH-3323),并将在下一个测试版中提供。

【讨论】:

谢谢!我通过设置最大结果和第一项来对所有查询使用分页,但这个特定情况将涵盖一组非常有限的最多 100 个项目,因为它们是只有几行文本的简单教育文章。因此,没有机会获得超过 100 或 120 个,一次性处理应该不是问题。 另一方面,您提供的滚动模式看起来也是不错的解决方案,因为我正在构建文章链接列表 - 实例化 URL 列表,运行查询并滚动查看所有文章并将他们的 URL 放入列表中。 @horvoje 您可能希望使用投影来从存储在索引中的数据加载 URL;这将为您节省数据库访问权限。更多信息:docs.jboss.org/hibernate/search/5.11/reference/en-US/…

以上是关于使用 Hibernate Search 查询并获取所有项目而无需分页的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate Search查询中的fullTextQuery.getResultList()上的com.google.gson.JsonArray.getAsString错误

[Hibernate Search] 基础查询

Hibernate Search 不索引/重新索引实体

如何使用Hibernate Search查询DSL匹配多个术语?

如何使用gradle获取Hibernate Search Lucene的所有依赖项?

Hibernate Search:如何正确使用通配符?