ES分组和查询

该代码实现了一个在Elasticsearch中进行分组查询的功能,根据不同的分组条件动态构建DSL,支持多级分组和日期类型的分组。同时,还提供了查询和排序功能,包括布尔查询、范围查询以及分页和排序设置。
摘要由CSDN通过智能技术生成

分组

 public Map<String, AggsResopnse> operateRecordInfo(PersonOperateRecordRequestEntity personOperateRecordRequest) {
        SearchRequest searchRequest = new SearchRequest(PERSON_OPERATE_RECORD_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (null != personOperateRecordRequest.getPersonNumber()) {
            boolQueryBuilder.must(QueryBuilders.termQuery(PERSON_NUMBER, personOperateRecordRequest.getPersonNumber()));
        }
        if (null != personOperateRecordRequest.getOperaterNumber()) {
            boolQueryBuilder.must(QueryBuilders.termQuery(OPERATER_NUMBER, personOperateRecordRequest.getOperaterNumber()));
        }
        searchSourceBuilder.query(boolQueryBuilder);
        //分组
        List<PersonOperateRecordRequestEntity.AggsModel> aggs = personOperateRecordRequest.getAggs();
        if (!CollectionUtils.isEmpty(aggs)) {
            int aggSize = 15;
            //将分组条件放入数组,目的是为了根据不同的分组条件,方便与动态化构建DSL
            ValuesSourceAggregationBuilder[] aggregationBuilders = new ValuesSourceAggregationBuilder[aggs.size()];
            for (PersonOperateRecordRequestEntity.AggsModel agg : aggs) {
                if (StringUtils.isBlank(agg.getDateGroup())) {
                    if (null != agg.getAggsSize()) {
                        aggSize = agg.getAggsSize();
                    }
                    //ES类型为字符的分组
                    aggregationBuilders[agg.getOrder()] = AggregationBuilders.terms(agg.getAggFiled()).field(agg.getAggFiled()).size(aggSize);
                } else {
                    //ES类型未日期的分组
                    aggregationBuilders[agg.getOrder()] = AggregationBuilders.dateHistogram(agg.getAggFiled())
                            .field(agg.getAggFiled())
                            //过滤掉0的
                            .minDocCount(0)
                            //显示日期格式化
                            .format(agg.getFormat())
                            //日期的起止时间与结束时间
                            .extendedBounds(new LongBounds(agg.getBoundsStart(), agg.getBoundsEnd()))
                            //日期分组的间隔
                            .calendarInterval(new DateHistogramInterval(agg.getDateGroup()));
                }
            }
            /**
             * 如果有两个及以上的分组条件,则倒数第二个包住倒数第一个,直到第一个包住第二个
             */
            for (int i = 0, len = aggregationBuilders.length - 1; i < len; len--) {
                aggregationBuilders[len - 1].subAggregation(aggregationBuilders[len]);
            }
            //最后只需要将第一个进行构建即可
            searchSourceBuilder.aggregation(aggregationBuilders[0]);
        }
        try {
            //只获取分组,则把size设为0
            searchSourceBuilder.size(0);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResult = esHelper.getClient().search(searchRequest, RequestOptions.DEFAULT);
            Aggregations aggResults = searchResult.getAggregations();
            //最后将结果封装
            Map<String, AggsResopnse> aggsResopnseMap = new HashMap<>((int) (aggs.size()/0.75+1));
            for (String s : aggResults.getAsMap().keySet()) {
                //MultiBucketsAggregation类可以将聚合的字符字段或者日期字段的对象同时封装
                MultiBucketsAggregation aggregation = aggResults.get(s);
                for (MultiBucketsAggregation.Bucket bucket : aggregation.getBuckets()) {
                    aggsResopnseMap.put(bucket.getKeyAsString(), recursion(bucket));
                }
            }
            return aggsResopnseMap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据桶进行递归,直到桶没有聚合数据为止,桶里面则放着分完组key
     * @param bucket
     * @return
     */
    private AggsResopnse recursion(MultiBucketsAggregation.Bucket bucket) {
        Map<String, AggsResopnse> aggsResopnseMap = null;
        //桶下的聚合
        Aggregations aggregations = bucket.getAggregations();
        for (String s : aggregations.getAsMap().keySet()) {
            MultiBucketsAggregation aggregation = aggregations.get(s);
            aggsResopnseMap = new HashMap<>((int) (aggregation.getBuckets().size()/0.75+1));
            for (MultiBucketsAggregation.Bucket bucket1 : aggregation.getBuckets()) {
                aggsResopnseMap.put(bucket1.getKeyAsString(), recursion(bucket1));
            }
        }
        //封装
        AggsResopnse aggsResopnse = new AggsResopnse();
        aggsResopnse.setCount(bucket.getDocCount());
        aggsResopnse.setAggs(aggsResopnseMap);
        return aggsResopnse;
    }

查询

public ESPage<PersonOperateRecordResopnseEntity> selectPersonOperateRecord(PersonOperateRecordRequestEntity personOperateRecordRequest) {
        List<PersonOperateRecordResopnseEntity> personOperateRecordResopnseEntities = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest(PERSON_OPERATE_RECORD_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (null != personOperateRecordRequest.getPersonNumber()) {
            boolQueryBuilder.must(QueryBuilders.termQuery(PERSON_NUMBER, personOperateRecordRequest.getPersonNumber()));
        }
        if (null != personOperateRecordRequest.getContent()) {
            boolQueryBuilder.must(QueryBuilders.termQuery(CONTENT, personOperateRecordRequest.getContent()));
        }
        if (null != personOperateRecordRequest.getOperaterNumber()) {
            boolQueryBuilder.must(QueryBuilders.termQuery(OPERATER_NUMBER, personOperateRecordRequest.getOperaterNumber()));
        }
        if (null != personOperateRecordRequest.getStartTime()) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery(CREATE_TIME).gte(personOperateRecordRequest.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
        }
        if (null != personOperateRecordRequest.getEndTime()) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery(CREATE_TIME).lte(personOperateRecordRequest.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
        }
        searchSourceBuilder.query(boolQueryBuilder);
        //排序及分页
        if (CollectionUtils.isEmpty(personOperateRecordRequest.getSortModels())) {
            SortBuilder<org.elasticsearch.search.sort.FieldSortBuilder> sortBuilder = SortBuilders.fieldSort(UID).order(SortOrder.DESC);
            searchSourceBuilder.sort(sortBuilder);
        } else {
            for (RequestModel.SortModel sortModel : personOperateRecordRequest.getSortModels()) {
                SortBuilder<org.elasticsearch.search.sort.FieldSortBuilder> sortBuilder = SortBuilders.fieldSort(sortModel.getFieldSort()).order(SortOrder.fromString(sortModel.getOrder()));
                searchSourceBuilder.sort(sortBuilder);
            }
        }
        searchSourceBuilder.size(personOperateRecordRequest.getSize());
        if (personOperateRecordRequest.getSearchAfter() != null) {
            searchSourceBuilder.searchAfter(personOperateRecordRequest.getSearchAfter());
        }
        try {
            searchSourceBuilder.trackTotalHits(true);
            searchRequest.source(searchSourceBuilder);
            SearchResponse response = esHelper.getClient().search(searchRequest, RequestOptions.DEFAULT);
            TotalHits totalHits = response.getHits().getTotalHits();
            SearchHit[] hits = response.getHits().getHits();
            for (SearchHit searchHit : hits) {
                String result = searchHit.getSourceAsString();
                PersonOperateRecordResopnseEntity personOperateRecordResopnse = JsonUtils.jsonToPojo(result, PersonOperateRecordResopnseEntity.class);
                personOperateRecordResopnse.setSearchAfter(searchHit.getSortValues());
                personOperateRecordResopnseEntities.add(personOperateRecordResopnse);
            }
            ESPage<PersonOperateRecordResopnseEntity> page = new ESPage<>();
            page.setList(personOperateRecordResopnseEntities);
            page.setTotal(totalHits.value);
            return page;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值