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

如何在OpenSearch中并行执行Term聚合查询?

在OpenSearch 2.17中实现单个查询内的多聚合并行执行

问题背景

我们有一个用于统计多字段词项数量的OpenSearch查询,DSL如下:

{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "your_filter_field": "your_filter_value"
          }
        }
      ]
    }
  },
  "aggs": {
    "aggregation_1": {
      "terms": {
        "field": "field_1"
      }
    },
    "aggregation_2": {
      "terms": {
        "field": "field_2"
      }
    },
    ...
    "aggregation_50": {
      "terms": {
        "field": "field_3"
      }
    }
  }
}

在OpenSearch 2.17版本中,这些顶级terms聚合会串行执行,导致查询速度较慢。目前采用multisearch将每个聚合拆分为单独请求的临时方案,虽然速度有所提升,但重复执行相同过滤器存在明显的资源浪费。需要找到在单个查询内并行执行多个聚合的方法。

解决方案

1. 验证聚合执行模式

首先通过profile API确认聚合是否真的串行执行,这有助于排查问题根源:

{
  "profile": true,
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "your_filter_field": "your_filter_value"
          }
        }
      ]
    }
  },
  "aggs": {
    "aggregation_1": {
      "terms": {
        "field": "field_1"
      }
    },
    ...
  }
}

查看返回的profile数据,重点关注聚合阶段的线程分配和执行顺序。

2. 调整并发分片请求配置

OpenSearch的search.max_concurrent_shard_requests参数控制单个搜索请求中并发分片请求的数量,默认值为5,可能不足以支撑多聚合并行。可以通过两种方式调整:

  • 全局配置:在opensearch.yml中修改参数(需重启节点生效):
    search.max_concurrent_shard_requests: 10
    
  • 请求级配置:在查询URL中添加参数,仅对当前请求生效:
    GET /your_index/_search?search_max_concurrent_shard_requests=10
    
    注意:该值不宜过高,避免给集群带来过大负载,建议根据节点数和硬件配置调整(比如设置为节点数的2-3倍)。

3. 重构聚合结构

将所有terms聚合嵌套在一个filter聚合下,确保过滤器仅执行一次,同时子聚合可以并行处理:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "filtered_dataset": {
      "filter": {
        "term": {
          "your_filter_field": "your_filter_value"
        }
      },
      "aggs": {
        "aggregation_1": {
          "terms": {
            "field": "field_1"
          }
        },
        "aggregation_2": {
          "terms": {
            "field": "field_2"
          }
        },
        ...
        "aggregation_50": {
          "terms": {
            "field": "field_3"
          }
        }
      }
    }
  }
}

这种结构下,过滤器会先对数据集进行一次过滤,然后所有子聚合基于过滤后的数据集并行执行,避免了重复过滤的开销。

4. 优化聚合参数

  • 为terms聚合设置合理的size值,避免不必要的计算和数据传输;
  • 如果字段是高基数字段,可启用show_term_doc_count_error来平衡性能和精度,但仅在必要时使用。

效果对比

采用上述方案后,单个查询内的多聚合会并行执行,既避免了multisearch的重复过滤开销,又能获得接近拆分请求的执行速度,同时降低了集群的请求负载。

内容的提问来源于stack exchange,提问作者Lukáš Křečan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:34:57