elasticsearch根据字段聚合后,排序取第一条记录

前言

使用elasticsearch查询分页时遇到需要先对某个条件聚合后再取每个桶中的第一条记录的情况,请教了下同事,再自身研究了一些时间才搞出来,特做此记录,希望也能帮到大家吧~ ~
这里用的elasticsearch版本是6.4.3。这里使用elasticsearch-head搞几条数据做测试例子…

概念及作用

bucket(桶)

简单来说就是满足特定条件的文档的集合

max

用于跟踪并返回从聚集的文档中提取的数值中的最大值

bucket_sort

bucket_sort聚合与所有管道聚合一样,在所有其他非管道聚合之后执行。这意味着排序只适用于已经从父聚合返回的任何bucket。

sort

根据字段排序

一、首先添加5条测试数据
索引:test,type:person

{
  "mappings": {
    "person": {
      "properties": {
        "name": {
          "type": "text"
        },
        "logTime": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss||epoch_millis"
        },
        "groupTime": {
          "type": "keyword"
        }
      }
    }
  }
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二、复合查询请求
在这里插入图片描述

{
  "from": 0,
  "size": 0,
  "query": {
    "bool": {}
  },
  "aggregations": {
    "groupTime": {
      "terms": {
        "field": "groupTime",
        "size": 2147483647,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "desc"
          }
        ]
      },
      "aggregations": {
        "sortTime": {
          "max": {
            "field": "logTime"
          }
        },
        "groupTime": {
          "top_hits": {
            "from": 0,
            "size": 1,
            "version": false,
            "explain": false,
            "_source": {
              "includes": [
                "name",
                "logTime",
                "groupTime"
              ],
              "excludes": []
            },
            "sort": [
              {
                "logTime": {
                  "order": "desc"
                }
              }
            ]
          }
        },
        "default_sort": {
          "bucket_sort": {
            "sort": [
              {
                "sortTime": {
                  "order": "desc"
                }
              }
            ],
            "from": 0,
            "gap_policy": "SKIP"
          }
        }
      }
    }
  }
}

三、请求结果
可以看出根据groupTime分组并根据logTime倒序,结果得出两条数据,并且各自取分组中时间最大的那一条数据
在这里插入图片描述

四、注意事项
需要注意的是,我groupTime设置为text字段时貌似聚合有问题,keyword类型字段没问题,所以groupTime字段设置为了keyword类型(其它类型没做尝试)。

这个也是我尝试多次后能得到我需要的结果的语句(本人也是个elasticsearch小白,不能说自己说的就对,只能大概说说我自己的理解)。
max会取桶中最大的值,而我需要的是不是一个值而是最大的值所在的那条记录的部分字段,所以先用sort倒序排序,然后采用max取到了桶中第一条记录,最后根据bucket_sort给得出的所有记录排序。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值