自动联想-聚合

/**
* 查询满足条件的结果
* @param esFieldRegex es的表达式
* @param queryValue 传入的参数
* @return
*/
public List<TopHitResult> queryAggregationResult(String esFieldRegex, String queryValue){
Map<String, String[]> fieldResult = Maps.newHashMap();
Map<String, String[]> queryResult = Maps.newHashMap();
resultFieldParamParse.buildKeyValueToResult(esFieldRegex, fieldResult);
resultQueryParamParse.buildKeyValueToResult(esFieldRegex, queryResult);
//获取要获取的字段名入口,并判断类型
String fieldName = fieldResult.keySet().stream().findFirst().orElse(StringUtils.EMPTY);
//获取对应的
EsBaseFieldInfo esDataByField = getEsDataByField(fieldName);
//根据类型选择不同的查询方式
AggregationCategory aggregationCategory = queryTopHitCenter.aggregationByType(esDataByField.getEsFieldType());
//执行封装queryBuilder
DefalutEsQueryBuilder defalutEsQueryBuilder = new DefalutEsQueryBuilder();
List<BaseEsQueryParam> baseEsQueryParamFromRegex = defalutEsQueryBuilder.getBaseEsQueryParamFromRegex(esFieldRegex);
//获取查询表达式中类型
Map<String, String> paramFieldType = new HashMap<>(10);
queryResult.forEach((key,value)->{
EsBaseFieldInfo esDataByName = getEsDataByField(key);
paramFieldType.put(key, esDataByName.getEsFieldType());
});
//这里有个坑,es在聚合的时候的,如果nest要加条件过滤不需要加nest的path,
// 不知道是不是es的bug,但是不符合一般的逻辑,所以这部如果是nest的类型,一律都按非nest来处理
if (!FieldType.Nested.name().equals(esDataByField.getEsFieldType())) {
baseEsQueryParamFromRegex.forEach(each->{
//获取当前参数查询的类型,主要判断是否是nest结构
EsBaseFieldInfo eachField = getEsDataByField(each.getParamName());
each.setDataType(eachField.getEsFieldType());
each.setParamFieldType(paramFieldType);
});
}
QueryBuilder queryBuilder = defalutEsQueryBuilder.buildQuery(baseEsQueryParamFromRegex);
return aggregationCategory.query(queryBuilder, fieldName, queryValue, this);
}
- 通用的查询defalutEsQueryBuilder.buildQuery(baseEsQueryParamFromRegex)
package com.ewell.ai.es.query;
import com.ewell.ai.es.constants.EsConstants;
import com.ewell.ai.es.entity.BaseEsQueryParam;
import com.ewell.ai.es.entity.QueryBuilderPool;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import java.util.List;
/**
* @author huajiejun
* @Date 2020/3/1 8:58 下午
*/
public class DefalutEsQueryBuilder extends AbstractEsQueryBuilder implements BaseEsQueryBuilder{
@Override
public QueryBuilder buildQuery(List<BaseEsQueryParam> baseEsQueryParams) {
//全部都是must的语句
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
baseEsQueryParams.forEach(each->{
//如果查询没有指定则默认为表达式方式
if (each.getSearchType() == null) {
each.setSearchType(EsConstants.SEARCH_TYPE_REGEX);
}
if (StringUtils.isEmpty(each.getParamName())) {
throw new RuntimeException("未配置es字段");
}
//表达式解析并封装为条件
QueryBuilderPool queryBuilderPool = queryBuilderFromParamWithRegex(each.getParamName(), String.valueOf(each.getParamValue()), each.getCompareType());
//进行解析
buildSearchQuery(boolQueryBuilder, each, queryBuilderPool, true);
});
return boolQueryBuilder;
}
}
分组聚合
@Override
public List<TopHitResult> query(QueryBuilder queryBuilder,String queryName, String queryValue, BaseEsIndex baseEsIndex) {
//=====1.方式一 嵌套表的查询
//定义要分组的嵌套表,自定义名称和对应的地址
NestedAggregationBuilder testInfoNestAggregation = AggregationBuilders.nested(GROUP_NEST, new ExportQueryBuilder().getPathFromParams(queryName));
//定义嵌套表的分组信息,根据什么分组,以及定义分组后的名称
TermsAggregationBuilder groupByTestResult = AggregationBuilders.terms(GROUP_BY_NEST_RESULT).field(queryName);
//注意是加载分组信息里面
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(queryBuilder);
//执行封装querybuilder
if (StringUtils.isNotEmpty(queryValue)) {
boolQueryBuilder = buildParamNameQueryBuilder(boolQueryBuilder, queryName, queryValue);
}
FilterAggregationBuilder aggregationBuilder = AggregationBuilders.filter(NEST_FILTER, boolQueryBuilder).subAggregation(groupByTestResult);
NestedAggregationBuilder nestedAggregationBuilder = testInfoNestAggregation.subAggregation(aggregationBuilder);
Aggregations aggregations =baseEsIndex.queryAggregation(nestedAggregationBuilder);
Nested groupTestInfo = aggregations.get(GROUP_NEST);
Filter testResultFilter = groupTestInfo.getAggregations().get(NEST_FILTER);
Terms groupByTest = testResultFilter.getAggregations().get(GROUP_BY_NEST_RESULT);
return getTopHitResults(groupByTest);
}