引言
最近小编负责的一个语音质检 项目中用到了ES,下面结合实例代码分享一下java操作ES查用的查询写法。
关于es的基本操作,例如新建索引、查询封装类,请参考前面博客:【ElasticSearch实战】——封装java操作es基础架构
1、ES在项目中的位置
2、项目查询需求
从上面查询条件来看,其中包括了精确查询,模糊查询及时间范围查询等,这些查询 都会在下面 样例代码中给出,并且还有部分统计的写法,例如机器质检不合格的数量, 人工审核不合格的数量等。
3、查询代码
package com.jack.search.es.service;
import com.jack.common.constant.SearchConstants;
import com.jack.search.es.model.CaseCallCheckListQueryInfo;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author zhenghao
* @description: 录音库查询
* @date 2019/10/1115:49
*/
@Service
public class CallCheckQueryService {
@Autowired
private QueryService queryService;
@Autowired
private ElasticSearchService elasticSearchService;
public Map<String, Object> getCallCheckList(CaseCallCheckListQueryInfo queryInfo) {
if (queryInfo == null) {
return null;
}
//构造查询条件
BoolQueryBuilder boolQueryBuilder = this.getCallCheckQueryBuilder(queryInfo);
//排序
String orderBy = queryInfo.getOrderBy();
if (StringUtils.isEmpty(orderBy)) {
orderBy = String.format("%s:%s", "telTime", "desc");
}
//分页
Integer pageNo = queryInfo.getPageNo();
if ((pageNo == null) || (pageNo <= 0)) {
pageNo = 0;
} else {
pageNo -= 1;
}
Integer pageSize = queryInfo.getPageSize();
if ((pageSize == null) || (pageSize < 1)) {
pageSize = 10;
}
//构造排序构造器FieldSortBuilder,设置排序参数
String[] orderStr = orderBy.split(":");
FieldSortBuilder sort = SortBuilders.fieldSort(orderStr[0]).order("desc".equalsIgnoreCase(orderStr[1])? SortOrder.DESC:SortOrder.ASC);
//AggregationBuilder 相当于 mysql中的 group by
//第一级机器质检不合格数据聚合 聚合名称为 hasError ,聚合数据条件为 字段 hasError>=1
FilterAggregationBuilder hasErrorAggregationBuilder = AggregationBuilders.filter("hasError", QueryBuilders.rangeQuery("hasError").gte(1));
//构造第二级子聚合 每一个质检项的值 >=1 注意:每一个checkItem 是一个字段,代表一个质检项 0代表没有命中该质检项,大于0代表表中
for (int i = SearchConstants.CHECK_ITEM_MIN; i<= SearchConstants.CHECK_ITEM_MAX; i++) {
String checkItemName = String.format("checkItem%d", i);
hasErrorAggregationBuilder.subAggregation(AggregationBuilders.filter(checkItemName, Que