统计聚合

使用统计聚合功能可以实现求最小值、求最大值、求和、求平均值、统计行数、去重统计行数、百分位统计、按字段值分组、按范围分组、按地理位置分组、按过滤条件分组、直方图统计、获取统计聚合分组内的行、嵌套查询等;同时多个统计聚合功能可以组合使用,满足复杂的查询需求。

流程

统计聚合的完整执行流程如下图所示。

fig_agg_pro

统计聚合是在服务端的“查询”结束后执行,服务端会将“查询”阶段命中的所有文档根据查询请求进行统计聚合,因此统计聚合请求相比没有统计聚合的请求会复杂。

背景信息

统计聚合的详细功能请参见下表。

功能

说明

最小值

返回一个字段中的最小值,类似于SQL中的min。

最大值

返回一个字段中的最大值,类似于SQL中的max。

返回数值字段的总数,类似于SQL中的sum。

平均值

返回数值字段的平均值,类似于SQL中的avg。

统计行数

返回指定字段值的数量或者多元索引数据总行数,类似于SQL中的count。

去重统计行数

返回指定字段不同值的数量,类似于SQL中的count(distinct)。

百分位统计

百分位统计常用来统计一组数据的百分位分布情况,例如在日常系统运维中统计每次请求访问的耗时情况时,需要关注系统请求耗时的P25、P50、P90、P99值等分布情况。

字段值分组

根据一个字段的值对查询结果进行分组,相同的字段值放到同一分组内,返回每个分组的值和该值对应的个数。

说明

当分组较大时,按字段值分组可能会存在误差。

范围分组

根据一个字段的范围对查询结果进行分组,字段值在某范围内放到同一分组内,返回每个范围中相应的item个数。

地理位置分组

根据距离某一个中心点的范围对查询结果进行分组,距离差值在某范围内放到同一分组内,返回每个范围中相应的item个数。

过滤条件分组

按照过滤条件对查询结果进行分组,获取每个过滤条件匹配到的数量,返回结果的顺序和添加过滤条件的顺序一致。

直方图统计

按照指定数据间隔对查询结果进行分组,字段值在相同范围内放到同一分组内,返回每个分组的值和该值对应的个数。

获取统计聚合分组中的行

对查询结果进行分组后,获取每个分组内的一些行数据,可实现和MySQLANY_VALUE(field)类似的功能。

嵌套

分组类型的统计聚合功能支持嵌套,其内部可以添加子统计聚合。

多个统计聚合

多个统计聚合功能可以组合使用。

说明

当多个统计聚合的复杂度较高时可能会影响响应速度。

前提条件

  • 已初始化OTSClient。具体操作,请参见初始化
  • 已创建数据表并写入数据。
  • 已在数据表上创建多元索引。具体操作,请参见创建多元索引

最小值

返回一个字段中的最小值,类似于SQL中的min。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、DoubleDate类型。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 最小值。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void MinAggregation(OTSClient otsClient)
    {
        MinAggregation minAggregation = new MinAggregation();
        minAggregation.AggName = "Min_Agg";
        minAggregation.FieldName = "pk1";
    
        RangeQuery rangeQuery = new RangeQuery();
        rangeQuery.FieldName = "pk1";
        rangeQuery.From = new ColumnValue(0);
        rangeQuery.To = new ColumnValue(100);
    
        SearchQuery seachQuery = new SearchQuery
        {
            Limit = 0,
            Query = rangeQuery,
            AggregationList = new List<IAggregation>
            {
                minAggregation
            }
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, seachQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse.AggregationResults.GetAsMinAggregationResult("Min_Agg")));
    }

最大值

返回一个字段中的最大值,类似于SQL中的max。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、DoubleDate类型。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 最大值。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void MaxAggregation(OTSClient otsClient)
    {
        MaxAggregation maxAggregation = new MaxAggregation();
        maxAggregation.AggName = "Max_Agg";
        maxAggregation.FieldName = "pk1";
    
        RangeQuery rangeQuery = new RangeQuery();
        rangeQuery.FieldName = "pk1";
        rangeQuery.From = new ColumnValue(0);
        rangeQuery.To = new ColumnValue(100);
    
        SearchQuery seachQuery = new SearchQuery
        {
            Limit = 0,
            Query = rangeQuery,
            AggregationList = new List<IAggregation>
            {
                maxAggregation
            }
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, seachQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse.AggregationResults.GetAsMaxAggregationResult("Max_Agg")));
    }

返回数值字段的总数,类似于SQL中的sum。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持LongDouble类型。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 求和。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void SumAggregation(OTSClient otsClient)
    {
        SumAggregation sumAggregation = new SumAggregation();
        sumAggregation.AggName = "Sum_Agg";
        sumAggregation.FieldName = "pk1";
    
        RangeQuery rangeQuery = new RangeQuery();
        rangeQuery.FieldName = "pk1";
        rangeQuery.From = new ColumnValue(0);
        rangeQuery.To = new ColumnValue(100);
    
        SearchQuery seachQuery = new SearchQuery
        {
            Limit = 0,
            Query = rangeQuery,
            AggregationList = new List<IAggregation>
            {
                sumAggregation
            }
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, seachQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse.AggregationResults.GetAsSumAggregationResult("Sum_Agg")));
    }

平均值

返回数值字段的平均值,类似于SQL中的avg。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、DoubleDate类型。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 求平均值。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void AvgAggregation(OTSClient otsClient)
    {
        AvgAggregation avgAggregation = new AvgAggregation();
        avgAggregation.AggName = "Avg_Agg";
        avgAggregation.FieldName = "pk1";
    
        RangeQuery rangeQuery = new RangeQuery();
        rangeQuery.FieldName = "pk1";
        rangeQuery.From = new ColumnValue(0);
        rangeQuery.To = new ColumnValue(100);
    
        SearchQuery seachQuery = new SearchQuery
        {
            Limit = 0,
            Query = rangeQuery,
            AggregationList = new List<IAggregation>
            {
                avgAggregation
            }
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, seachQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse.AggregationResults.GetAsAvgAggregationResult("Avg_Agg")));
    }

统计行数

返回指定字段值的数量或者多元索引数据总行数,类似于SQL中的count。

说明

通过如下方式可以统计多元索引数据总行数或者某个query匹配的行数。

  • 使用统计聚合的count功能,在请求中设置count(*)。

  • 使用query功能的匹配行数,在query中设置setGetTotalCount(true);如果需要统计多元索引数据总行数,则使用MatchAllQuery。

如果需要获取多元索引数据某列出现的次数,则使用count(列名),可应用于稀疏列的场景。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、Double、Boolean、Keyword、Geo_pointDate类型。

  • 示例

    /// <summary>
    /// 统计行数。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void CountAggregation(OTSClient otsClient)
    {
        CountAggregation countAggregation = new CountAggregation();
        countAggregation.AggName = "Count_Agg";
        countAggregation.FieldName = "pk1";
    
        RangeQuery rangeQuery = new RangeQuery();
        rangeQuery.FieldName = "pk1";
        rangeQuery.From = new ColumnValue(0);
        rangeQuery.To = new ColumnValue(100);
    
        SearchQuery seachQuery = new SearchQuery
        {
            Limit = 0,
            Query = rangeQuery,
            AggregationList = new List<IAggregation>
            {
                countAggregation
            }
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, seachQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse.AggregationResults.GetAsCountAggregationResult("Count_Agg")));
    }

去重统计行数

返回指定字段不同值的数量,类似于SQL中的count(distinct)。

说明

去重统计行数的计算结果是个近似值。

  • 当去重统计行数小于1万时,计算结果接近精确值。

  • 当去重统计行数达到1亿时,计算结果的误差为2%左右。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、Double、Boolean、Keyword、Geo_pointDate类型。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 去重统计行数。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void DistinctCountAggregation(OTSClient otsClient)
    {
        DistinctCountAggregation distinctCountAggregation = new DistinctCountAggregation();
        distinctCountAggregation.AggName = "DistinctCount_Agg";
        distinctCountAggregation.FieldName = "pk1";
    
        TermsQuery termsQuery = new TermsQuery();
        termsQuery.FieldName = "pk0";
        termsQuery.Terms = new List<ColumnValue>
        {
            new ColumnValue("Sample"),
            new ColumnValue("SearchIndex")
        };
    
        SearchQuery seachQuery = new SearchQuery
        {
            Limit = 0,
            Query = termsQuery,
            AggregationList = new List<IAggregation>
            {
                distinctCountAggregation
            }
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, seachQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse.AggregationResults.GetAsDistinctCountAggregationResult("DistinctCount_Agg")));
    }

百分位统计

百分位统计常用来统计一组数据的百分位分布情况,例如在日常系统运维中统计每次请求访问的耗时情况时,需要关注系统请求耗时的P25、P50、P90、P99值等分布情况。

说明

百分位统计为非精确统计,对不同百分位数值的计算精确度不同,较为极端的百分位数值更加准确,例如1%或99%的百分位数值会比50%的百分位数值准确。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、DoubleDate类型。

    Percentiles

    百分位分布例如50、90、99,可根据需要设置一个或者多个百分位。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 百分位统计。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void PercentilesAggregation(OTSClient otsClient)
    {
        PercentilesAggregation percentilesAggregation = new PercentilesAggregation();
        percentilesAggregation.AggName = "Percentiles_Agg";
        percentilesAggregation.FieldName = "pk1";
        percentilesAggregation.Missing = new ColumnValue(10);
        percentilesAggregation.Percentiles = new List<double> { 10.0, 30.0, 60.0, 90.0, 100.0 };
    
        MatchAllQuery matchAllQuery = new MatchAllQuery();
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.AggregationList = new List<IAggregation> { percentilesAggregation };
        searchQuery.Query = matchAllQuery;
        searchQuery.Limit = 0;
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse));
    }

字段值分组

根据一个字段的值对查询结果进行分组,相同的字段值放到同一分组内,返回每个分组的值和该值对应的个数。

说明

当分组较大时,按字段值分组可能会存在误差。

  • 参数

    参数

    说明

    GroupByName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Long、Double、Boolean、KeywordDate类型。

    Size

    返回的分组数量,默认值为10。最大值为2000。当分组数量超过2000时,只会返回前2000个分组。

    GroupBySorters

    分组中的item排序规则,默认按照分组中item的数量降序排序,多个排序则按照添加的顺序进行排列。支持的参数如下:

    • 按照值的字典序升序排列

    • 按照值的字典序降序排列

    • 按照行数升序排列

    • 按照行数降序排列

    • 按照子统计聚合结果中值升序排列

    • 按照子统计聚合结果中值降序排列

    SubAggregationSubGroupBy

    子统计聚合,子统计聚合会根据分组内容再进行一次统计聚合分析。

    • 场景

      统计每个类别的商品数量,且统计每个类别价格的最大值和最小值。

    • 方法

      最外层的统计聚合是根据类别进行分组,再添加两个子统计聚合求价格的最大值和最小值。

    • 结果示例

      • 水果:5个(其中价格的最大值为15,最小值为3)

      • 洗漱用品:10个(其中价格的最大值为98,最小值为1)

      • 电子设备:3个(其中价格的最大值为8699,最小值为2300)

      • 其它:15个(其中价格的最大值为1000,最小值为80)

  • 示例

    /// <summary>
    /// 字段值分组。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void GroupByField(OTSClient otsClient)
    {
        GroupByField groupByField = new GroupByField
        {
            GroupByName = "GroupBy_Field",
            FieldName = "pk0",
            GroupBySorters = new List<GroupBySorter>{
                new GroupBySorter()
                {
                    RowCountSort = new RowCountSort{ Order = SortOrder.DESC }
                },
                new GroupBySorter()
                {
                    GroupKeySort = new GroupKeySort{ Order = SortOrder.DESC }
                }
            }
        };
    
        MatchAllQuery matchAllQuery = new MatchAllQuery();
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.GroupByList = new List<IGroupBy> { groupByField };
        searchQuery.Query = matchAllQuery;
        searchQuery.Limit = 0;
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse));
    }

范围分组

根据一个字段的范围对查询结果进行分组,字段值在某范围内放到同一分组内,返回每个范围中相应的item个数。

  • 参数

    参数

    说明

    GroupByName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持LongDouble类型。

    Range[double_from, double_to)

    分组的范围。

    起始值double_from可以使用最小值double.MinValue,结束值double_to可以使用最大值double.MaxValue。

    SubAggregationSubGroupBy

    子统计聚合,子统计聚合会根据分组内容再进行一次统计聚合分析。

    例如按销量分组后再按省份分组,即可获得某个销量范围内哪个省比重比较大,实现方法是GroupByRange下添加一个GroupByField。

  • 示例

    /// <summary>
    /// 范围分组。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void GroupByRange(OTSClient otsClient)
    {
        GroupByRange groupByRange = new GroupByRange();
        groupByRange.GroupByName = "GroupBy_Range";
        groupByRange.FieldName = "pk1";
        groupByRange.Ranges = new List<Range>
        {
            new Range(double.MinValue, 5.0),
            new Range(5.0, 50.0),
            new Range(50.0, 100.0),
            new Range(100.0, double.MaxValue)
        };
    
        MatchAllQuery matchAllQuery = new MatchAllQuery();
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.GroupByList = new List<IGroupBy> { groupByRange };
        searchQuery.Query = matchAllQuery;
        searchQuery.Limit = 0;
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse));
    }

地理位置分组

根据距离某一个中心点的范围对查询结果进行分组,距离差值在某范围内放到同一分组内,返回每个范围中相应的item个数。

  • 参数

    参数

    说明

    GroupByName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持Geo_point类型。

    Origin(double latitude, double longitude)

    起始中心点的经纬度。

    latitude是起始中心点坐标纬度,longitude是起始中心点坐标经度。

    Range[double_from, double_to)

    分组的范围,单位为米。

    起始值double_from可以使用最小值double.MinValue,结束值double_to可以使用最大值double.MaxValue。

    SubAggregationSubGroupBy

    子统计聚合,子统计聚合会根据分组内容再进行一次统计聚合分析。

  • 示例

    /// <summary>
    /// 地理位置分组。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void GroupByGeoDistance(OTSClient otsClient)
    {
        GroupByGeoDistance groupByGeoDistance = new GroupByGeoDistance
        {
            GroupByName = "GroupBy_GeoDistance",
            FieldName = "geo_col",
            Origin = new GeoPoint(0, 0),
            Ranges = new List<Range>
            {
                new Range(double.MinValue , 1000.0),
                new Range(1000.0, 5000.0),
                new Range(5000.0, double.MaxValue)
            }
        };
    
        MatchAllQuery matchAllQuery = new MatchAllQuery();
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.GroupByList = new List<IGroupBy> { groupByGeoDistance };
        searchQuery.Query = matchAllQuery;
        searchQuery.Limit = 0;
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse));
    }

过滤条件分组

按照过滤条件对查询结果进行分组,获取每个过滤条件匹配到的数量,返回结果的顺序和添加过滤条件的顺序一致。

  • 参数

    参数

    说明

    GroupByName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    Filters

    过滤条件,返回结果的顺序和添加过滤条件的顺序一致。

    SubAggregationSubGroupBy

    子统计聚合,子统计聚合会根据分组内容再进行一次统计聚合分析。

  • 示例

    /// <summary>
    /// 过滤条件分组。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void GroupByFilter(OTSClient otsClient)
    {
        GroupByFilter groupByFilter = new GroupByFilter
        {
            GroupByName = "GroupBy_Filter",
            Filters = new List<IQuery>
            {
                new RangeQuery
                {
                    FieldName = "pk1",
                    From = new ColumnValue(0.0),
                    To = new ColumnValue(5.0)
                },
            }
        };
    
        TermsQuery termsQuery = new TermsQuery();
        termsQuery.FieldName = "pk0";
        termsQuery.Terms = new List<ColumnValue>
        {
            new ColumnValue("Tablestore SearchIndex"),
            new ColumnValue("SearchIndex")
        };
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.GroupByList = new List<IGroupBy> { groupByFilter };
        searchQuery.Query = termsQuery;
        searchQuery.Limit = 0;
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        Console.WriteLine(JsonConvert.SerializeObject(searchResponse));
    }

直方图统计

按照指定数据间隔对查询结果进行分组,字段值在相同范围内放到同一分组内,返回每个分组的值和该值对应的个数。

  • 参数

    参数

    说明

    GroupByName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    FieldName

    用于统计聚合的字段,仅支持LongDouble类型。

    Interval

    统计间隔。

    FieldRange[min,max]

    统计范围,与Interval参数配合使用限制分组的数量。(FieldRange.max-FieldRange.min)/Interval的值不能超过2000。

    MinDocCount

    最小行数。当分组中的行数小于最小行数时,不会返回此分组的统计结果。

    Missing

    当某行数据中的字段为空时,字段值的默认值。

    • 如果未设置Missing值,则在统计聚合时会忽略该行。

    • 如果设置了Missing值,则使用Missing值作为字段值的默认值参与统计聚合。

  • 示例

    /// <summary>
    /// 直方图统计。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void HistogramAggregation(OTSClient otsClient)
    {
        GroupByHistogram groupByHistogram = new GroupByHistogram();
        groupByHistogram.GroupByName = "GroupBy_Histogram";
        groupByHistogram.FieldName = "pk1";
        groupByHistogram.Interval = new ColumnValue(5);
        groupByHistogram.Missing = new ColumnValue(100);
        groupByHistogram.FieldRange = new FieldRange(new ColumnValue(0), new ColumnValue(1000));
    
        MatchAllQuery matchAllQuery = new MatchAllQuery(); ;
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.Query = matchAllQuery;
        searchQuery.Limit = 0;
        searchQuery.GroupByList = new List<IGroupBy>
        {
            groupByHistogram
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        foreach (GroupByHistogramResultItem item in searchResponse.GroupByResults.GetAsGroupByHistogramResult("GroupBy_Histogram").GroupByHistogramResultItems)
        {
            Console.WriteLine(JsonConvert.SerializeObject(item));
        }
    }

获取统计聚合分组中的行

对查询结果进行分组后,获取每个分组内的一些行数据,可实现和MySQLANY_VALUE(field)类似的功能。

说明

获取统计聚合分组中的行时,如果多元索引中包含嵌套类型、地理位置类型或者数组类型的字段,则返回结果中只会包含主键信息,请手动反查数据表获取所需字段。

  • 参数

    参数

    说明

    AggName

    自定义的统计聚合名称,用于区分不同的统计聚合,可根据此名称获取本次统计聚合结果。

    Limit

    每个分组内最多返回的数据行数,默认返回1行数据。

    Sort

    分组内数据的排序方式。

    ColumnsToGet

    指定返回的字段,仅支持多元索引中的字段,且不支持数组、Date、GeopointNested类型的字段。

    该参数复用SearchRequest中的columnsToGet参数,在SearchRequest中指定columnsToGet即可。

  • 示例

    /// <summary>
    /// 获取统计聚合分组中的行。
    /// </summary>
    /// <param name="otsClient"></param>
    public static void TopRowsAggregation(OTSClient otsClient)
    {
        GroupByField groupByField = new GroupByField();
        groupByField.GroupByName = "GroupBy_Field";
        groupByField.FieldName = "pk0";
        groupByField.SubAggregations = new List<IAggregation>
        {
            new TopRowsAggregation
            {
                AggName = "TopRows_Agg",
                Sort = new Sort(new List<ISorter> { new FieldSort("pk1", SortOrder.DESC) }),
                Limit = 2
            }
        };
    
        MatchAllQuery matchAllQuery = new MatchAllQuery(); ;
    
        SearchQuery searchQuery = new SearchQuery();
        searchQuery.Query = matchAllQuery;
        searchQuery.Limit = 0;
        searchQuery.GroupByList = new List<IGroupBy>
        {
            groupByField
        };
    
        SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);
    
        SearchResponse searchResponse = otsClient.Search(searchRequest);
    
        foreach (GroupByFieldResultItem item in searchResponse.GroupByResults.GetAsGroupByFieldResult("GroupBy_Field").GroupByFieldResultItems)
        {
            foreach (Row row in item.SubAggregationResults.GetAsTopRowsAggregationResult("TopRows_Agg").Rows)
            {
                Console.WriteLine(JsonConvert.SerializeObject(row));
            }
        }
    }

嵌套

分组类型的统计聚合功能支持嵌套,其内部可以添加子统计聚合。

主要用于在分组内再次进行统计聚合,以两层的嵌套为例:

  • GroupBy+SubGroupBy:按省份分组后再按照城市分组,获取每个省份下每个城市的数据。

  • GroupBy+SubAggregation:按照省份分组后再求某个指标的最大值,获取每个省的某个指标最大值。

说明

为了性能、复杂度等综合考虑,嵌套的层级只开放了一定的层数。更多信息,请参见多元索引限制

/// <summary>
/// 嵌套。
/// </summary>
/// <param name="otsClient"></param>
public static void SubGroupBy(OTSClient otsClient)
{
    GroupByField groupByField = new GroupByField();
    groupByField.GroupByName = "Field_GroupBy";
    groupByField.FieldName = "pk0";
    groupByField.SubGroupBys = new List<IGroupBy>
    {
        new GroupByRange
        {
            GroupByName = "Range_GroupBy",
            FieldName = "pk1",
            Ranges = new List<Range>
            {
                new Range(double.MinValue, 5),
                new Range(5,100),
                new Range(100, double.MaxValue)
            }

        }
    };

    MatchAllQuery matchAllQuery = new MatchAllQuery();

    SearchQuery searchQuery = new SearchQuery();
    searchQuery.GroupByList = new List<IGroupBy>
    {
        groupByField
    };
    searchQuery.GetTotalCount = true;
    searchQuery.Limit = 0;
    searchQuery.Query = matchAllQuery;

    SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);

    SearchResponse searchResponse = otsClient.Search(searchRequest);

    foreach (GroupByFieldResultItem item in searchResponse.GroupByResults.GetAsGroupByFieldResult("Field_GroupBy").GroupByFieldResultItems)
    {
        Console.WriteLine(JsonConvert.SerializeObject(item.SubGroupByResults.GetAsGroupByRangeResult("Range_GroupBy")));
    }
}

多个统计聚合

多个统计聚合功能可以组合使用。

说明

当多个统计聚合的复杂度较高时可能会影响响应速度。

/// <summary>
/// 多个统计聚合。
/// </summary>
/// <param name="otsClient"></param>
public static void MultipleAggregation(OTSClient otsClient)
{
    MaxAggregation maxAggregation = new MaxAggregation();
    maxAggregation.AggName = "Max_Agg";
    maxAggregation.FieldName = "pk1";

    MinAggregation minAggregation = new MinAggregation();
    minAggregation.AggName = "Min_Agg";
    minAggregation.FieldName = "pk1";

    SumAggregation sumAggregation = new SumAggregation();
    sumAggregation.AggName = "Sum_Agg";
    sumAggregation.FieldName = "pk1";

    SearchQuery searchQuery = new SearchQuery();
    searchQuery.Limit = 0;
    searchQuery.Query = new MatchAllQuery();
    searchQuery.AggregationList = new List<IAggregation>
    {
        maxAggregation,
        minAggregation,
        sumAggregation
    };

    SearchRequest searchRequest = new SearchRequest(TableName, IndexName, searchQuery);

    SearchResponse searchResponse = otsClient.Search(searchRequest);

    Console.WriteLine(JsonConvert.SerializeObject(searchResponse));
}