es group by max并显示非group by 的其他字段

一.sql 示例

假设有如下数据

	SELECT 
	"1" as id,"001" as card,1 as sequenceNo, 1 as resultStatus
	UNION ALL
	SELECT
	"2" as id,"001" as card,2 as sequenceNo, 2 as resultStatus
	UNION ALL
	SELECT
	"3" as id,"001" as card,3 as sequenceNo, 3 as resultStatus
	UNION ALL
	SELECT
	"4" as id,"002" as card,1 as sequenceNo, 1 as resultStatus
	UNION ALL
	SELECT
	"5" as id,"002" as card,2 as sequenceNo, 3 as resultStatus

在这里插入图片描述
需要拿到每个card最大的sequenceNo,那么sql这么写

 SELECT max(sequenceNo),aa.card from aa GROUP BY aa.card

es 的 写法

{
  "from": 0,
  "size": 0,
  "query": {
    "bool": {
      "must": [
                    {
                      "terms": {
                        "card": [
                          "aa",
                          ""
                        ]
                      }
                    }
                  ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "aggregations": {
    "cardAsName": {
      "terms": {
        "field": "card",
        "size": 9999,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false
      },
      "aggregations": {
        "maxSequenceNo": {
          "max": {
            "field": "sequenceNo"
          }
        }
      }
    }
  }
}

es代码说明

size: 表示不需要查询的hits结果,因为group by 的结果集在aggregations 的 buckets
aggregations: 聚合查询,可以嵌套,第一层是group by ,第二层可以理解是对这个group by 的结果进行max,和上面的sql效果一样
maxSequenceNo:别名,随便取
max: 代表是用的 max 函数

结果示例
在这里插入图片描述

java查询代码示例

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //聚合查询,不需要hits
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(0);
        
TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("groupName")
            .field("field1")
            .size(9999);
            
termsBuilder.subAggregation(AggregationBuilders.max("maxNo")
    .field("field2"));
            
List<FieldSortBuilder> fieldSorts = new ArrayList<>();
//按大小排序
fieldSorts.add(new FieldSortBuilder("maxNo").order(SortOrder.DESC));
termsBuilder.subAggregation(new BucketSortPipelineAggregationBuilder("bucket_field", fieldSorts)
    //这里才是真正的分页参数
    .from(request.getOffsetStart())
    .size(request.getPageSize()));
    
searchSourceBuilder.aggregation(termsBuilder);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
searchSourceBuilder.query(boolQueryBuilder);
        
SearchRequest searchRequest = new SearchRequest("you es index ");
SearchRequest searchRequest = new SearchRequest(index);
SearchResponse source = searchRequest.source(searchSourceBuilder);

//结果处理

Terms terms = (Terms) source.getAggregations()
            .asMap()
            .get("groupName");
            
List<? extends Terms.Bucket> termsBuckets = terms.getBuckets();

for (Terms.Bucket termsBucket : termsBuckets) {
    String key = termsBucket.getKeyAsString();
    ParsedMax parsedMax = (ParsedMax) termsBucket.getAggregations()
        .asMap()
        .get("maxNo");
    long maxNo = (long) parsedMax.getValue();
}

如果需要返回其他字段,需要 结合 top_hits 取第一条文档
JAVA代码示例

//对结果top取第一条
        TopHitsAggregationBuilder topHitsAggregationBuilder = AggregationBuilders.topHits("TOP_HIT_NO_NAME")
            .from(0)
            .size(1)
            .fetchSource(new String[] {"field1",
                "field2"}, null)
            .sort(new FieldSortBuilder("field1").order(SortOrder.DESC)
                .unmappedType("long"));

//解析示例
SearchResponse source = es结果;

Terms terms = (Terms) source.getAggregations()
            .asMap()
            .get(FLOW_INSTANCE_ID_ANOTHER_NAME);
Terms terms = (Terms) source.getAggregations()
            .asMap()
            .get("groupName");
            
List<? extends Terms.Bucket> termsBuckets = terms.getBuckets();

for (Terms.Bucket termsBucket : termsBuckets) {
    String key= termsBucket.getKeyAsString();
    ParsedTopHits parsedTopHits = (ParsedTopHits) termsBucket.getAggregations()
        .asMap()
        .get("TOP_HIT_NO_NAME");
    SearchHit hit = parsedTopHits.getHits()
        .getHits()[0];
    Object flowNodeExecStatus = hit.getSourceAsMap()
        .get("field1");

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值