首页 > 解决方案 > 使用 Hibernate Search 查询并获取所有项目而无需分页

问题描述

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

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

标签: javaspring-bootlucenehibernate-searchpageable

解决方案


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

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

休眠搜索 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();

在许多情况下,它不起作用或性能不佳,因为命中占用了太多内存。

理想情况下,您应该改用滚动

这是 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 ) 并将在下一个测试版中提供。


推荐阅读