ElasticSearch 聚合和OR条件查询(通过一个输入框实现创建人或名称查询)

2021/12/28 6:07:11

本文主要是介绍ElasticSearch 聚合和OR条件查询(通过一个输入框实现创建人或名称查询),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

OR条件查询
ES条件查询中有MUST/MUSTNOT/SHOULD逻辑,其中MUST/MUSTNOT与sql中的AND/NOT理解和用法基本一致,但SHOULD则与sql中的OR有些不一样,在ES中如果要表示OR查询,则需要配合MUST一起使用,即MUST(SHOULD A, SHOULD B),表示A OR B

    BoolQueryBuilder pinyinQuery = QueryBuilders.boolQuery();
    if (!keyword.contains("-")) {
        pinyinQuery.should(QueryBuilders.matchQuery("userName.pinyin", pinyin));
    }
    pinyinQuery.should(QueryBuilders.termQuery("userId", keyword));
          
    BoolQueryBuilder queryEs = QueryBuilders.boolQuery()
            .must(pinyinQuery)
            .must(new TermQueryBuilder("officeStatus", "1"));
    // 构造highlight
    HighlightBuilder hiBuilder= new HighlightBuilder();
    hiBuilder.preTags("<h2>").postTags("</h2>").field("userName.pinyin");
    SearchResponse scrollRes =
            client.prepareSearch(ES_INDEX_NAME)
                    .setTypes(ES_INDEX_USER_TYPE)
                    .setQuery(queryEs)
                    .highlighter(hiBuilder)
                    .setScroll("10s")
                    .setSize(1000)
                    .get();

分组聚合查询

实现类似select avg(executionTime) from t WHERE executionDate between 'A' AND 'B' group by executionDate ORDER BY executionDate ASC的查询后聚合。ES分组计算的逻辑是先将executionDate分组,然后在每个分组内在进行聚合,在API中是两个聚合aggregation包含的逻辑关系。

    //1.先对executionDate分组,取名executionDateGroup,即实现group by executionDate,如果不设置size,则聚合返回默认10组数据
    TermsAggregationBuilder groupTerms = AggregationBuilders.terms("executionDateGroup").field("executionDate").size(Integer.MAX_VALUE);
    //设置排序 true为正序、flase为倒序,实现ORDER BY executionDate ASC
    groupTerms.order(BucketOrder.key(true));
    
    //2.聚合avg(executionTime),取名executionTimeAvg
    AvgAggregationBuilder timeAvg = AggregationBuilders.avg("executionTimeAvg").field("executionTime");
    
    //3.两个aggregation父子关系
    groupTerms.subAggregation(timeAvg);
    
    //查询条件
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    RangeQueryBuilder rangeDateQuery = QueryBuilders.rangeQuery("executionDate").gte(DateFormatUtils.format(fromDate, "yyyy-MM-dd HH:mm:ss"))
            .lte(DateFormatUtils.format(toDate, "yyyy-MM-dd HH:mm:ss"));
    queryBuilder.must(rangeDateQuery);
    //如果方法名不为空,则添加查询条件
    if (StringUtils.isNotBlank(condition.getMethodName())) {
        queryBuilder.must(new TermQueryBuilder("methodName", condition.getMethodName()));
    }
    SearchResponse searchRes = esClient.prepareSearch(CommonConstants.EHR_EXCUTION_AOP_LOG_INDEX)
            .setTypes(CommonConstants.EHR_EXCUTION_AOP_LOG_TYPE)
            .setQuery(queryBuilder)
            .addAggregation(groupTerms)  //设置聚合
            .addSort("executionDate", SortOrder.ASC)
            .get();
    
    // 获取结果,提取结果的顺序与aggregation组合关系一致,先提取外层executionDateGroup,再提取多个分组的子层executionTimeAvg
    Aggregation executionDateGroup = searchRes.getAggregations().get("executionDateGroup");
    Terms timeAvgTerms = null;
    if (executionDateGroup instanceof Terms) {
        //外层aggregation
        timeAvgTerms = (Terms) executionDateGroup;
        List<? extends Terms.Bucket> buckets = timeAvgTerms.getBuckets();
        for (Terms.Bucket elem : buckets) {
            //子级aggregation
            InternalAvg executionTimeAvg = (InternalAvg) elem.getAggregations().get("executionTimeAvg");
            ExecutionInfoDto executionInfoDto = new ExecutionInfoDto();
            executionInfoDto.setExecutionDate(elem.getKeyAsString());
            executionInfoDto.setExecutionTime((int)executionTimeAvg.getValue());
            executionInfoDtoList.add(executionInfoDto);
        }
    }

 



原文链接:https://blog.csdn.net/ljyhust/article/details/87278243



这篇关于ElasticSearch 聚合和OR条件查询(通过一个输入框实现创建人或名称查询)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程