java中es的QueryBuilder的构建方式
这里只列举经常使用的,都是基于boolQuery查询。
1.查询list条件 termsQuery,常用于状态值,id等
2.查询单个条件 termQuery,常用于字符串查询,如名称等
3.查询范围 rangeQuery,常用于一个范围查询,如价格区间等
4.搜索词拆分模糊查询 matchQuery,常用于内容检索,如文章内容等
5.子查询 hasChildQuery,子查询最好用should连接
public QueryBuilder getQueryBuilder(SaasSearchBean searchBean) {
//去构建一个BoolQueryBuilder(多条件查询)
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 1.BId业务id QueryBuilders.termsQuery查询list条件
if (!searchBean.getBID().isEmpty()) {
boolQueryBuilder.filter(QueryBuilders.termsQuery("bid", searchBean.getBID()));
}
// 2.名称 QueryBuilders.termQuery查询单个条件
if (searchBean.getName() != null) {
boolQueryBuilder.filter(QueryBuilders.termQuery("name", searchBean.getName()));
}
// 3.创建时间 QueryBuilders.rangeQuery查询范围
if (searchBean.getCreated() != null) {
boolQueryBuilder.filter(QueryBuilders.rangeQuery("created").gte(0).lte(999));
}
// 4.描述 boolQueryBuilder.must分词查询
//matchQuery:会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到。
//termQuery:不会对搜索词进行分词处理,而是作为一个整体与目标字段进行匹配,若完全匹配,则可查询到。
if (searchBean.getDesc() != null) {
boolQueryBuilder.must(QueryBuilders.matchQuery("desc", searchBean.getDesc()).operator(Operator.AND));
}
//5.状态 子查询 (这块复杂) 7.x语法变了 待整理
//QueryBuilders.hasChildQuery查child_status索引的数据,childStatusQuery封装的是子索引的查询条件
//QueryBuilder childStatusQuery =QueryBuilders.hasChildQuery("child_status",QueryBuilders.boolQuery().filter(QueryBuilders.termsQuery("status",searchBean.getStatus())),ScoreMode.None);
//shouldQueryBuilder.should为or查询,不同于filter的and查询
//BoolQueryBuilder boolQueryBuilder =QueryBuilders.boolQuery();
//shouldQueryBuilder.should(childStatusQuery);
//将子查询中的查询关系设置为or,不会对父查询的索引有影响,以filfter的方式(and)将子查询关联进来
//boolQueryBuilder.filter(shouldQueryBuilder);
// 多值查询 用于一个字段查多组内容,详细见实现类
StringmultiSearchValue = searchBean.getMultiSearchValue();
BoolQueryBuilder multiSearchQueryBuilder = multipleSearchQueryService.getMultiSearchQueryBuilder(multiSearchValue);
Optional.ofNullable(multiSearchQueryBuilder).ifPresent(boolQueryBuilder::filter);
return boolQueryBuilder;
}
这里使用了一段多值查询multiSearchQueryBuilder。
内部其实就是一个should关系,实际应用场景一般是一个输入框,但要同时支持查询编号和名称。
public BoolQueryBuilder getMultiSearchQueryBuilder(String multipleSearchValue) {
BoolQueryBuilder queryBuilder =QueryBuilders.boolQuery();
//同时查询name和id,类似于 name =x or id = x
if (multipleSearchValue != null && !"".equals(multipleSearchValue)) {
queryBuilder.should(QueryBuilders.matchPhraseQuery("name", multipleSearchValue));
queryBuilder.should(QueryBuilders.termsQuery("bId", multipleSearchValue));
}
//至少匹配一项
queryBuilder.minimumShouldMatch(1);
return queryBuilder;
}
放在最后,这三种查询的区别
match和match_phase的输入都会进行分词,而match_phase要求返回的内容必须包含所有分词和顺序一致。
term输入不会分词,对于分词后的结果是查询不出来的。
1. match
match:模糊匹配,需要指定字段名,但是输入会进行分词,比如"helloworld"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者 world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模 糊查询。查询条件相对来说比较宽松。
2. term
term: 这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那 么会和match查询结果一样,但是如果查询"helloworld",结果就相差很大,因 为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否 有"helloworld"的字样,而不是查询字段中包含"hello world"的字样。当保存 数据"helloworld"时,elasticsearch会对字段内容进行分词,"hello world"会 被分成hello和world,不存在"helloworld",因此这里的查询结果会为空。这也 是term查询和match的区别。
3. match_phase
match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要 求一样。以"helloworld"为例,要求结果中必须包含hello和world,而且还要求 他们是连着的,顺序也是固定的,hello thatword不满足,world hello也不满 足条件。