最近在做一个基于Elasticsearch的项目,发现
spring-data-elasticsearch
组件提供的CRUD功能特别好用。但是使用中发现分页的功能,即spring-data
提供的Pagalbe
,Slice
功能实际不能正确分页的bug。且该Bug影响了目前spring-data-elasticsearch的3.0~3.1.0 M1版本,至今未修复。
好用的spring-data-elasticsearch
与分页功能
spring-data-elasticsearch
提供了各种基于CrudRepository
的便利CRUD操作后,可以自动将基本的查询检索操作翻译成Elasticsearch的Query DSL。只要按照简单易学的spring-data
的schema编写Repository的接口名,就可像使用Mybatis一样使用elasticsearch。
特别的,只要在interface中带上Pageable
的输入参数,就能自动实现分页的效果(spring doc)。例如:
Page<Article> articleByAuthorName
= articleService.findByAuthorName(nameToFind, PageRequest.of(0, 10));
Slice<Article> articleByAuthorNameAsSlice
= articleService.findByAuthorNameAsSlice(nameToFind, PageRequest.of(0, 10));
其中返回参数Page
和Slice
的区别是:Page
对象会计算结果集的totalCount,在数据量大时会有一定的计算代价;而Slice
不会计算总结果数量,只知道是否hasNext()
。
类似的,用Slice
做大结果集的遍历,也非常简单。可用自带的nextPagable
计算下一页的偏移量。
while (slice.hasNext()) {
slice = eventRepository.findByAppId(appId, slice.nextPageable());
result.addAll(slice.getContent());
}
惨遇分页bug
但是!这么方便的功能,在目前版本中是不能正常运作的!
现在是2018年4月,在Spring project主页上的版本从3.0.6到3.1.0 M1都有这个Bug的!
在spring的jira上DATAES-396,DATAES-402就是反映这个这个Blocker级别的bug。从2017年9月份发布3.0支持Elasticsearch 5后就有这个bug了,相关热心开发者也提供了PR,但是直到最近(约2018年3月)才被merge进master分支!
其实导致这个错误的代码就一行,在FacetedPageImpl
的构造函数中,将Pageable写死成了Pageable.unpaged()
:
public FacetedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, Pageable.unpaged(), total);
}
改起来也很简单:
public FacetedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, ofNullable(pageable).orElse(Pageable.unpaged()), total);
}
为什么响应这么慢?
在搜索这个问题过程中,有人在stackoverflow上反映,不仅这种紧急的bug未能及时修复,还抱怨spring-data-elasticsearch
未能跟上elstic的开发脚步(spring data es目前支持到了Elasticsearch 5, 而elstico现在已推出了6.3版本,提供了rollup,shrink等api)。
下面有人附和到,他去参加了spring的一个相关会议,spring的总架构师,把spring-data-elasticsearch
划分到了community project。也就是说,剩下的维护大多靠社区的PR,官方不会那么及时的跟进elastic的步伐。一句话总结就是:没娘的项目惨兮兮。
(那个讨论贴,忘了记录下来,现在找不到了地址了)
经历了这次事件后,再也不迷信Spring
的项目就是高质量的项目。对于开源软件框架等,存一份质疑之心。知其然,也要知其所以然。
最后,期望spring-data-elasticsearch
尽快发布3.1 release版本。查看Spring calendar,好像近期都没有计划。 ::cry::