Appearance
如何使用 hibernate Search 进行导出的时候 search after 的操作
项目中使用的版本是: hibernate-search 7.0.0.Final 的版本
搜索模块: https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-sorting
在关联的 org.hibernate.search.engine.search.query.SearchQuery 以及 SearchFetchable 类下,没有看到 searchAfter 方法,只看到 scroll 方法
可能是 Hibernate Search 7.0 处于有限支持状态
这里转换为使用 原生的 ES 特性(项目使用的ES是 8 以上的版本)
了解一下 scroll 方法: https://blog.csdn.net/zx711166/article/details/82426387 (滚动查询,建议使用 search_after, search_after 是 ES5.0 及之后版本提供的新特性)
ES 原生的写法 是有 searchAfter 的直接调用方法的
这里是使用 hibernate search 的部分内容, 并且加入部分 json 的拼写操作
这种写法能够直接更改 body 的内容
最后的更新版本代码
default Page<SalesOrderProduct> findSalesOrderProductPaginatedByCriteriaForExport(FindSalesOrderProductPaginatedRequest request, PageRequest pageRequest) {
int maxQuantity = 10000;
if (pageRequest.getOffset() + pageRequest.getPageSize() > maxQuantity) {
throw new GenericException(GenericException.Code.SEARCH_RANGE_TOO_LARGE);
}
SearchMapping searchMapping = App.getBean(SearchMapping.class);
try (SearchSession session = searchMapping.createSession()) {
int offset = (request.getSearchAfterValues() != null
&& request.getSearchAfterValues().getId() != null
&& request.getSearchAfterValues().getUpdatedAtTimestamp() != null)
? 0
: (int) pageRequest.getOffset();
SearchResult<SalesOrderProductEsDTO> searchResult = session.search(SalesOrderProductEsMapper.class)
.extension(ElasticsearchExtension.get())
.select(f -> f.composite()
.from(f.field("docId", Long.class), f.field("updatedAt", LocalDateTime.class))
.asList(list -> new SalesOrderProductEsDTO((Long) list.get(0), (LocalDateTime) list.get(1))))
.where(predicateContributor(request))
.requestTransformer(context -> {
if (request.getSearchAfterValues() != null
&& request.getSearchAfterValues().getId() != null
&& request.getSearchAfterValues().getUpdatedAtTimestamp() != null) {
JsonArray searchAfter = new JsonArray();
SalesOrderProductEsDTO lastResult = request.getSearchAfterValues();
searchAfter.add(lastResult.getUpdatedAtTimestamp());
searchAfter.add(lastResult.getId().toString());
context.body().add("search_after", searchAfter);
}
})
.sort(sortContributor(pageRequest))
.fetch(offset, pageRequest.getPageSize());
List<SalesOrderProductEsDTO> hits = searchResult.hits();
if (hits != null && !hits.isEmpty()) {
request.setSearchAfterValues(hits.get(hits.size() - 1));
}
List<Long> ids = searchResult.hits().stream().map(SalesOrderProductEsDTO::getId).collect(Collectors.toList());
return new PageImpl<>(findSortedByIdIn(ids), pageRequest, searchResult.total().hitCount());
}
}