
# 聚合分析增强
在处理大规模数据时，用户经常面临聚合查询性能低、分析效率低的问题。CSS服务的OpenSearch集群聚合增强功能通过向量化技术和数据聚簇优化，显著提升大规模数据的聚合查询分析性能，帮助用户在复杂数据场景中实现高效分析和提升业务决策效率。
#### 功能介绍
聚合增强功能的核心原理是通过合理设置排序键（Sort Key）和聚簇键（Clustering Key）在数据写入时对数据进行预排序和物理聚簇，从而减少查询时聚合过程中的数据扫描和计算开销。
- 排序键：数据按指定字段（如时间戳）顺序存储，确保相同值或相近值的文档在磁盘上连续分布。
- 聚簇键：作为排序键的前缀子集（如各城市订单数），进一步将数据聚簇，使聚合操作可批量处理连续数据块，而非逐条遍历。
 
例如，对于包含region、host、value三个字段的索引，在写入时文档将按region、host、value字段顺序排序，并按region和host字段进行聚簇存储。相同region和host组合的文档在物理上连续存储，且在聚簇内部按value字段的有序排列。
聚合查询可直接按聚簇键（region和host）进行查询，或在同一聚簇内基于value字段的取值范围进行批量查询，从而提升查询效率。
图1聚合增强示例   
![](https://support.huaweicloud.com/usermanual-css/figure/zh-cn_image_0000002510653374.png "点击放大")
表1聚合增强的适用场景 
| 场景          | 描述                                                              |
|:---|:---|
| 低基字段聚合      | 字段值种类较少，适合分组聚合。例如，统计各城市订单数量时，数据聚簇后可快速定位并批量处理。                   |
| 高基字段聚合      | 字段值种类繁多，适合直方图聚合。例如，按小时统计访问量时，使用排序键可加速区间数据的聚合。                   |
| 低基和高基字段混合聚合 | 先对低基字段使用聚簇键进行分组（如各城市订单），再对高基字段使用排序键进行直方图聚合（如时间），通过多级聚簇提升混合查询效率。 |
   
#### 约束限制
仅当OpenSearch集群版本号为2.19.0或3.4.0（镜像版本不低于3.4.0_26.6.0_xxx）时，才支持聚合增强功能。
#### 登录OpenSearch Dashboards
登录OpenSearch Dashboards进入命令执行页面。OpenSearch集群支持多种客户端访问，本文仅以CSS服务集成的OpenSearch Dashboards为例介绍配置指导。
1. 登录[云搜索服务管理控制台](https://console.huaweicloud.com/elasticsearch/)。
2. 在左侧导航栏，选择"集群管理 \> OpenSearch"。
3. 在集群列表，选择目标集群，单击操作列的"Dashboards"，登录OpenSearch Dashboards。
4. 在OpenSearch Dashboards左侧导航栏选择"Dev Tools"，进入操作页面。 控制台左侧是命令输入框，其右侧的三角形图标为执行按钮，右侧区域则显示执行结果。
   
 
#### 低基字段聚合
低基字段一般采用分组聚合，在排序的情况下具备较好的数据聚簇性，利于批量处理数据。
例如，当需要对"city"和"product"这两个低基字段进行聚合增强时，可以执行以下操作步骤实现聚合任务。
1. 执行如下命令，设置索引testindex。
   ```
   PUT testindex
   {
     "mappings": {
       "properties": {
         "date": {
           "type": "date",
           "format": "yyyy-MM-dd"
         },
         "city": {
           "type": "keyword"
         },
         "product": {
           "type": "keyword"
         },
         "trade": {
           "type": "double"
         }
       }
     },
     "settings": {
       "index": {
         "search": {
           "turbo": {
             "enabled": "true" 
           }
         },
         "sort": {
           "field": [
             "city",
             "product"
           ]
         },
         "cluster": {
           "field": [
             "city",
             "product"
           ]
         }
       }
     }
   }
   ```
   表2低基字段聚合的参数说明 
   | 参数                         | 类型               | 默认值   | 说明                                                                                                                                                                                                                                                                                                                                                                                                                    |
   |:---|:---|:---|:---|
   | index.search.turbo.enabled | Boolean          | false | 是否启用聚合增强功能。使用聚合分析时必须启用聚合增强功能。 取值范围： - false：不启用聚合增强。  - true：启用聚合增强。   |
   | index.sort.field           | Array of strings | 无     | 指定排序键。排序键用于定义文档排序所依据的字段。 在配置排序键时，可以指定一个或多个字段。当多个字段被指定时，排序将按照字段的顺序依次进行。第一个字段的排序结果将作为主要排序依据，第二个字段则在第一个字段排序结果的基础上进行次级排序，以此类推。 取值范围：必须是索引包含的字段。                                                                                                                                                                          |
   | index.cluster.field        | Array of strings | 无     | 指定聚簇键。聚簇键用于对文档进行聚簇处理，具有相同键值的文档会被归类到同一聚簇中。 在进行聚合操作时，同一聚簇内的文档能够被批量处理，从而显著提升聚合性能。 约束限制：聚簇键必须是排序键的前缀子集。 取值范围：必须是索引包含的字段。                                                                                                                                                       |
      
   
2. 执行如下命令，导入样例数据。
   ```
   PUT /_bulk
   { "index": { "_index": "testindex", "_id": "1" } }
   { "date": "2025-01-01", "city": "cityA", "product": "books", "trade": 3000.0}
   { "index": { "_index": "testindex", "_id": "2" } }
   { "date": "2025-01-02", "city": "cityA", "product": "books", "trade": 1000.0}
   { "index": { "_index": "testindex", "_id": "3" } }
   { "date": "2025-01-01", "city": "cityA", "product": "bottles", "trade": 100.0}
   { "index": { "_index": "testindex", "_id": "4" } }
   { "date": "2025-01-02", "city": "cityA", "product": "bottles", "trade": 300.0}
   { "index": { "_index": "testindex", "_id": "5" } }
   { "date": "2025-01-01", "city": "cityB", "product": "books", "trade": 7000.0}
   { "index": { "_index": "testindex", "_id": "6" } }
   { "date": "2025-01-02", "city": "cityB", "product": "books", "trade": 1000.0}
   ```
   
3. 执行查询命令，实现低基字段聚合查询。 例如，查询不同city下每个product的trade平均值：
   ```
   POST testindex/_search
   {
     "size": 0,
     "aggs": {
       "groupby_city": {
         "terms": {
           "field": "city"
         },
         "aggs": {
           "groupby_product": {
             "terms": {
               "field": "product"
             },
             "aggs": {
               "avg_trade": {
                 "avg": {
                   "field": "trade"
                 }
               }
             }
           }
         }
       }
     }
   }
   ```
   
 
#### 高基字段聚合
高基字段一般采用排序键进行直方图分组聚合，利于处理某个区间内的数据。
例如，当需要对典型的高基字段"date"进行聚合增强时，可以执行以下操作步骤实现聚合任务。
1. 执行如下命令，设置索引testindex。
   ```
   PUT testindex
   {
     "mappings": {
       "properties": {
         "date": {
           "type": "date",
           "format": "yyyy-MM-dd"
         },
         "score": {
           "type": "double"
         }
       }
     },
     "settings": {
       "index": {
         "search": {
           "turbo": {
             "enabled": "true" 
           }
         },
         "sort": {
           "field": [
             "date"
           ]
         }
       }
     }
   }
   ```
   表3高基字段聚合的参数说明 
   | 参数                         | 类型               | 默认值   | 说明                                                                                                                                                                                                                                                                                                                                                                                                              |
   |:---|:---|:---|:---|
   | index.search.turbo.enabled | Boolean          | false | 是否启用聚合增强功能。使用聚合分析时必须启用聚合增强功能。 取值范围： - false：不启用聚合增强。  - true：启用聚合增强。   |
   | index.sort.field           | Array of strings | 无     | 指定排序键。排序键用于定义文档排序所依据的字段。 在配置排序键时，可以指定一个或多个字段。当多个字段被指定时，排序将按照字段的顺序依次进行。第一个字段的排序结果将作为主要排序依据，第二个字段则在第一个字段排序结果的基础上进行次级排序，以此类推。 取值范围：必须是索引包含的字段。                                                                                                                                                                       |
      
   
2. 执行如下命令，导入样例数据。
   ```
   PUT /_bulk
   { "index": { "_index": "testindex", "_id": "1" } }
   { "date": "2025-01-01", "score": "12.0"}
   { "index": { "_index": "testindex", "_id": "2" } }
   { "date": "2025-01-02","score": "24.0"}
   { "index": { "_index": "testindex", "_id": "3" } }
   { "date": "2025-01-01","score": "53.0"}
   { "index": { "_index": "testindex", "_id": "4" } }
   { "date": "2025-01-02", "score": "22.0"}
   { "index": { "_index": "testindex", "_id": "5" } }
   { "date": "2025-01-01", "score": "99.0"}
   { "index": { "_index": "testindex", "_id": "6" } }
   { "date": "2025-01-02","score": "26.0"}
   ```
   
3. 执行查询命令，实现高基字段聚合查询。 该聚合任务是对时间字段date做直方图分组，然后求score的平均值。
   ```
   POST testindex/_search?pretty
   {
     "size": 0,
     "aggs": {
       "groupbytime": {
         "date_histogram": {
           "field": "date",
           "calendar_interval": "day"
         },
         "aggs": {
           "avg_score": {
             "avg": {
               "field": "score"
             }
           }
         }
       }
     }
   }
   ```
   
 
#### 低基和高基字段混合聚合
在低基字段和高基字段混合的场景下，一般先对低基字段使用聚簇键进行分组，然后再对高基字段使用排序键进行直方图聚合。
例如，当需要先对"city"低基字段进行分组，再对"product"低基字段进行分组，最后对"date"高基字段进行直方图分组时，可以执行以下操作步骤实现聚合任务。
1. 执行如下命令，设置索引testindex。
   ```
   PUT testindex
   {
     "mappings": {
       "properties": {
         "date": {
           "type": "date",
           "format": "yyyy-MM-dd"
         },
         "city": {
           "type": "keyword"
         },
         "product": {
           "type": "keyword"
         },
         "trade": {
           "type": "double"
         }
       }
     },
     "settings": {
       "index": {
         "search": {
           "turbo": {
             "enabled": "true"
           }
         },
         "sort": { 
           "field": [
             "city",
             "product",
             "date"
           ]
         },
         "cluster": {
           "field": [
             "city",
             "product"
           ]
         }
       }
     }
   }
   ```
   表4低基和高基字段混合聚合的参数说明 
   | 参数                         | 类型               | 默认值   | 说明                                                                                                                                                                                                                                                                                                                                                                                                                   |
   |:---|:---|:---|:---|
   | index.search.turbo.enabled | Boolean          | false | 是否启用聚合增强功能。使用聚合分析时必须启用聚合增强功能。 取值范围： - false：不启用聚合增强。  - true：启用聚合增强。   |
   | index.sort.field           | Array of strings | 无     | 指定排序键。排序键用于定义文档排序所依据的字段。 在配置排序键时，可以指定一个或多个字段。当多个字段被指定时，排序将按照字段的顺序依次进行。第一个字段的排序结果将作为主要排序依据，第二个字段则在第一个字段排序结果的基础上进行次级排序，以此类推。 约束限制：高基字段必须在排序键中，且高基字段必须在最后一个低基字段后面。 取值范围：必须是索引包含的字段。                                                                                        |
   | index.cluster.field        | Array of strings | 无     | 指定聚簇键。聚簇键用于对文档进行聚簇处理，具有相同键值的文档会被归类到同一聚簇中。 在进行聚合操作时，同一聚簇内的文档能够被批量处理，从而显著提升聚合性能。 约束限制：聚簇键必须是排序键的前缀子集。 取值范围：必须是索引包含的字段。                                                                                                                                                     |
      
   
2. 执行如下命令，导入样例数据。
   ```
   PUT /_bulk
   { "index": { "_index": "testindex", "_id": "1" } }
   { "date": "2025-01-01", "city": "cityA", "product": "books", "trade": 3000.0}
   { "index": { "_index": "testindex", "_id": "2" } }
   { "date": "2025-01-02", "city": "cityA", "product": "books", "trade": 1000.0}
   { "index": { "_index": "testindex", "_id": "3" } }
   { "date": "2025-01-01", "city": "cityA", "product": "bottles", "trade": 100.0}
   { "index": { "_index": "testindex", "_id": "4" } }
   { "date": "2025-01-02", "city": "cityA", "product": "bottles", "trade": 300.0}
   { "index": { "_index": "testindex", "_id": "5" } }
   { "date": "2025-01-01", "city": "cityB", "product": "books", "trade": 7000.0}
   { "index": { "_index": "testindex", "_id": "6" } }
   { "date": "2025-01-02", "city": "cityB", "product": "books", "trade": 1000.0}
   ```
   
3. 执行查询命令，实现低基和高基字段混合聚合查询。 例如，查询不同city下每个product的在date字段每天的trade平均值：
   ```
   POST testindex/_search
   {
     "size": 0,
     "aggs": {
       "groupby_region": {
         "terms": {
           "field": "city"
         },
         "aggs": {
           "groupby_host": {
             "terms": {
               "field": "product"
             },
             "aggs": {
               "groupby_timestamp": {
                 "date_histogram": {
                   "field": "date",
                   "interval": "day"
                 },
                 "aggs": {
                   "avg_score": {
                     "avg": {
                       "field": "trade"
                     }
                   }
                 }
               }
             }
           }
         }
       }
     }
   }
   ```
   
 
