whats new in v2.0.0-beta1
# v2.0.0-beta1
2.0.0-beta1是Easy-Es2023年的第一个版本,很抱歉2.0版本姗姗来迟.
本次带来的是一个里程碑版本,并非小版本,因此旷日持久,其中四大嵌套查询类型的算法零零总总花了近一年碎片时间探索.
2.0.0-beta1提供了10余项新特性,10余项增强,1个Bug修复,以及官网文档进一步完善和提供完整的项目介绍PPT.
# 何时发布2.0.0正式版?
计划在今年上半年完成2.0正式版发布,这已经比原规划整整提前了半年时间 之所以先发布了v2.0.0-beta1是因为本次2.0版本改动确实非常大,核心代码几乎改了一遍, 为了保证2.0.0正式版稳性和可靠性,为EE赢得口碑,我们计划以4个版本进行推送
- v2.0.0-beta1 推送全部特性及改进
- v2.0.0-beta2 推送jackson替换fastjson 版本 并改进beta1中出现的反馈及修复可能出现的缺陷
- v2.0.0-beta3 推送beta2中的改进以及修复可能出现的缺陷
- v2.0.0 推送正式版
# 2.0.0-beta1可以用于生产吗?
我的答案是可以,但前提是你会自己修改源码,或者贵公司使用ES的场景不核心,比如就基本的文档检索或者一些非2C的业务,尽管我们版本名叫beta, 但是上线前都是做了严格测试的,有大量自动化测试用例覆盖,确保核心功能稳定可靠,用户在使用过程中针对开发好的功能还可以再次测试,如此基本上可以完成生产 所需要求,万不得已有既知缺陷时,您可以通过混合及原生查询来解决,或是修改源码等途径,并且我们也会在beta2中及时修复beta1中出现的缺陷.
# 四大嵌套查询支持
关于这块其实一共有进行过2次算法调整,加上这次一共是第三次,其中前面两次由于走在了错误的路上,所以绞尽脑汁也未能实现最佳的效果, 所以2.X之前的版本在超过2层嵌套的复杂查询是不能通过开箱即用的方式来实现的.经过长达一年的探索,终于解决了4种嵌套查询,并且支持无级嵌套, 无论查询条件多么复杂,层级多么深,都可以轻松拿捏.
MySQL | Mybatis-Plus | ES | Easy-Es |
---|---|---|---|
and 拼接 | 默认 | must | 默认 |
or 拼接 | or() | should | or() |
无 | 无 | filter | filter() |
无 | 无 | must_not | not() |
直观对比
// MySQL语法
where business_type = 1
and (state = 9 or (state = 8 and bidding_sign = 1))
or (business_type = 2 and state in (2,3));
// Easy-Es及Mybatis-Plus语法
wrapper.eq("business_type", 1)
.and(a -> a.eq("state", 9).or(b -> b.eq("state", 8).eq("bidding_sign", 1)))
.or(i -> i.eq("business_type", 2).in("state", 2, 3));
// ES原生的RestHighLevel语法
List<Integer> values = Arrays.asList(2, 3);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("business_type", 1));
boolQueryBuilder.must(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("state", 9))
.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("state", 8))
.must(QueryBuilders.termQuery("bidding_sign", 1))));
boolQueryBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("business_type", 2))
.must(QueryBuilders.termsQuery("state", values)));
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
上面的例子树的最大深度仅为2,如果深度超过2以后ES原生语法就很难看得懂了,更别说正确编码,就算您是ES老手也容易栽坑里,但现在你可以通过EE 1:1轻松又简单还原复杂SQL.
# 对嵌套类型的全部查询支持
在1.X的版本中,嵌套类型的开箱即用查询API仅支持了match一种查询,在2.x版本中则可以支持es全部的嵌套类型查询,以Consumer传入即可,社区开发者@lym贡献
- API
nested(String path, Consumer<Param> consumer);
- 使用demo
@Test
public void testNestedMatch() {
// 嵌套查询 查询年龄等于18或8,且密码等于123的数据
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.nested(FieldUtils.val(Document::getUsers), w ->
w.in(FieldUtils.val(User::getAge), 18, 8)
.eq(FieldUtils.val(User::getPassword), "123"));
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}
2
3
4
5
6
7
8
9
10
# 根据上下文自动拼接.keyword后缀
索引创建时默认的字段类型由keyword调整为text_keyword双类型,并且在查询时会根据查询类型和注解配置的类型自动智能拼接.keyword后缀, 且可以通过配置开启/关闭自动拼接,可增强字段的查询功能支持范围,减少用户工作量,并显著减少小白踩ES坑的可能.
# 所有条件构造器支持链式
所有条件构造器都支持链式调用(含索引),和MP一样的链式编程
@Test
public void testOne() {
// 链式调用
Document document = EsWrappers.lambdaChainQuery(documentMapper).eq(Document::getTitle, "测试文档3").one();
}
2
3
4
5
# 距离获取更简单了
@Distance获取距离注解,新增支持多字段,多排序器功能,并且不再需要用户手动指定排序迭代器位置,由框架全自动处理,使用更简单.
# 其它新特性
- 新增字段类型 wildcard类型 手自动挡均适用
- 提供索引手动刷新接口,触发由用户自由控制,之前索引刷新策略配置仍保留 自动+手动配齐
- 提供支持直接执行静态DSL语句的功能
- 提供直接执行SQL API
- 提供通过自定义注解设置路由功能
# 其它优化
- 移除原有not打头API,以及表示取反的API(历史原因,设计不合理,决定彻底废弃),比如notIn,notBetween,NE等,如今所有表示取反的都可以直接通过四大嵌套类型中提供的not解决
- 将geo地理位置查询并入Bool查询条件,也可以享受must/should/filter/mustNot, 原功能不受影响,可以理解为功能更强更灵活
- 废弃了配置项enableMust2Filter,可以直接用filter嵌套 更简单,更规范,粒度更细
- 重构了WrapperProcess核心逻辑以及AbstractWrapper核心逻辑 代码结构更清晰,核心逻辑比原来更简单易读,基本上傻瓜级了,易维护性维护更上一层楼
- 标记过时FieldType中的array类型和object类型,并通过注释说明应当使用的正确类型 防止es小白踩坑
- 调整重建索引超时时间默认值为72H,以及socketTimeOut等多个参数的默认数值,进一步防止小白踩坑索引迁移超时失败
- 增加默认最大连接超时时间,心跳时间,并且给予了一个合适的值,尽量帮助不懂ES的小白白少踩坑
- @Distance获取距离注解,新增支持多字段,多排序器功能,并且不再需要用户手动指定排序迭代器位置,由框架全自动处理,使用更简单.
- 进一步丰富了官网文档,使用更加傻瓜级,并且源码中每个重载方法都加了注释,使用起来编辑器提示更加友好.
# 缺陷修复
修复部分场景下@Distance距离注解保留距离小数位不准确缺陷