自动联想-聚合

/**
     * 查询满足条件的结果
     * @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);
    }
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);
    }