You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch 8.7.1:限制terms聚合中每个itemId的响应条数

问题描述

使用Elasticsearch 8.7.1版本查询时,希望限制每个itemDetails.itemId对应的返回记录数(例如设置size=2时,每个itemId返回2条记录),但当前查询返回了所有distinct cId的结果,不符合预期。


示例Elasticsearch文档

{
  "itemDetails": {
    "itemId": "3076",
    "usecase": "habc",
    "usecaseId": "xyz"
  },
  "metaData": {
    "cId": "96ff54507c2d018e5c767785c705a5b2",
    "date1": "2023-09-29T12:29:54",
    "date2": "2023-09-29T12:30:09"
  },
  // 其他属性...
}

当前输入查询语句

POST /index/_search?typed_keys=true
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "itemDetails.itemId": [
              "3076",
              "1111",
              "2222"
            ]
          }
        },
        {
          "terms": {
            "itemDetails.usecase": [
              "habc"
            ]
          }
        },
        {
          "range": {
            "metaData.date1": {
              "lte": "2023-09-30T19:55:54.611Z",
              "gte": "2023-09-27T19:55:54.611Z"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "distinct_cIds": {
      "terms": {
        "field": "metaData.cId",
        "order": { "max_date1": "desc" }
      },
      "aggs": {
        "max_date1": { 
          "max": { "field": "metaData.date1" } 
        },
        "top_doc": {
          "top_hits": {
            "size": 1,
            "sort": [
               {"metaData.date1": "desc"},          
               {"metaData.date2": "desc"}          
            ],
            "_source": {
              "includes": [
                        "itemDetails.itemId",
                        "itemDetails.usecase",
                        "metaData.cId",
                        "metaData.date1"
              ]
            }
          }
        }
      }
    }
  }
}

当前返回响应问题

返回结果会遍历所有distinct cId并输出对应记录,无法实现按itemId限制返回数量的需求,示例响应片段:

"buckets": [
  {
    "key": "f8d79b2856e894c9e88852f65120e9e3",
    "doc_count": 1,
    "sterms#distinct_itemId": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "3076",
          "doc_count": 1,
          "top_hits#top_doc": {
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": null,
              "hits": [{}]
            }
          }
        }
      ]
    },
    "max#max_date1": {
      "value": 1697385179000,
      "value_as_string": "2023-10-15T15:52:59.000Z"
    }
  },
  {
    "key": "153c067041341dc4d2052313d3f0891f",
    "doc_count": 1,
    "sterms#distinct_itemId": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "3076",
          "doc_count": 1,
          "top_hits#top_doc": {
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": null,
              "hits": [{}]
            }
          }
        }
      ]
    },
    "max#max_date1": {
      "value": 1697303179000,
      "value_as_string": "2023-10-14T17:06:19.000Z"
    }
  }
  // 更多cId记录...
]

解决方案

调整聚合层级,先按itemDetails.itemId分桶,再在每个itemId桶内通过top_hits聚合获取指定数量的记录(比如size=2),即可实现每个itemId限制返回条数的需求:

POST /index/_search?typed_keys=true
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "itemDetails.itemId": ["3076", "1111", "2222"]
          }
        },
        {
          "terms": {
            "itemDetails.usecase": ["habc"]
          }
        },
        {
          "range": {
            "metaData.date1": {
              "lte": "2023-09-30T19:55:54.611Z",
              "gte": "2023-09-27T19:55:54.611Z"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "per_itemId": {
      "terms": {
        "field": "itemDetails.itemId",
        "include": ["3076", "1111", "2222"], // 可选,与query过滤保持一致
        "size": 3 // 对应指定的3个itemId数量
      },
      "aggs": {
        "top_records": {
          "top_hits": {
            "size": 2, // 每个itemId返回2条记录
            "sort": [
              {"metaData.date1": "desc"},
              {"metaData.date2": "desc"}
            ],
            "_source": {
              "includes": [
                "itemDetails.itemId",
                "itemDetails.usecase",
                "metaData.cId",
                "metaData.date1"
              ]
            }
          }
        }
      }
    }
  }
}

说明

  • 外层聚合per_itemId按itemDetails.itemId分桶,确保每个itemId单独统计;
  • 内层top_records聚合通过size参数控制每个itemId返回的记录数,同时保留原有的排序规则;
  • include和size参数可选,因为query已经过滤了目标itemId,加上后能更精准地限制聚合范围。

内容的提问来源于Stack Exchange,提问作者Amulya M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 09:17:37