Todos os produtos
Search
Central de documentação

Tablestore:Agregação

Última atualização: Jul 03, 2026

Execute operações de agregação para obter valor mínimo, valor máximo, soma, média, contagem e contagem distinta de linhas. Agrupe resultados por valor de campo, intervalo, localização geográfica, filtro, histograma ou histograma de datas e realize consultas aninhadas. Combine múltiplas operações de agregação para atender a cenários de consulta complexos.

Informações básicas

A tabela a seguir descreve os métodos de agregação disponíveis.

Método

Descrição

Valor mínimo

Retorna o valor mínimo de um campo. Funciona de maneira semelhante à função MIN do SQL.

Valor máximo

Retorna o valor máximo de um campo. Equivalente à função MAX do SQL.

Soma

Calcula a soma de todos os valores de um campo numérico. Comportamento similar à função SUM do SQL.

Valor médio

Obtém a média de todos os valores de um campo numérico. Corresponde à função AVG do SQL.

Contagem

Retorna o número total de valores de um campo específico ou o total de linhas em um índice de busca. Análogo à função COUNT do SQL.

Contagem distinta

Indica a quantidade de valores únicos em um campo. Similar à função COUNT(DISTINCT) do SQL.

Agrupamento por valor de campo

Agrupa os resultados da consulta com base nos valores dos campos. Valores idênticos são reunidos no mesmo grupo. O sistema retorna o valor de cada grupo e a respectiva contagem de ocorrências.

Nota

O valor calculado pode divergir do valor real quando o volume de dados em um grupo for extremamente alto.

Agrupamento por múltiplos campos

O método de agregação que pode ser usado para agrupar resultados de consulta com base em múltiplos campos. Você pode usar tokens para realizar paginação.

Agrupamento por intervalo

Organiza os resultados em grupos conforme faixas de valores definidas para um campo. Retorna a quantidade de itens em cada intervalo especificado.

Agrupamento por localização geográfica

Classifica os resultados com base na distância entre as localizações geográficas e um ponto central. Itens dentro de faixas de distância predefinidas são agrupados, retornando a contagem por intervalo.

Agrupamento por filtro

Aplica filtros aos resultados da consulta e agrupa-os para contar quantos itens correspondem a cada condição. A ordem de retorno segue a sequência em que os filtros foram definidos.

Consulta por histograma

Distribui os resultados em intervalos de dados fixos. Valores dentro da mesma faixa formam um grupo. Retorna o intervalo e a contagem de valores de cada grupo.

Consulta por histograma de datas

Segmenta os resultados com base em intervalos temporais específicos. Agrupa valores que caem no mesmo período e devolve o intervalo e a contagem correspondente.

Aninhamento

Múltiplas agregações

Possibilita a execução combinada de diversas operações de agregação.

Nota

Operações complexas simultâneas podem aumentar significativamente o tempo de processamento.

Pré-requisitos

Valor mínimo

Retorna o valor mínimo de um campo. Este método funciona de forma análoga à função MIN do SQL.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Nome exclusivo da operação de agregação. Utilize este identificador para recuperar os resultados específicos desta agregação.

    FieldName

    Campo alvo para a operação de agregação. Aceita apenas os tipos de dados LONG, DOUBLE e DATE.

    Missing

    Valor padrão assumido pelo campo quando uma linha não possui valor definido para ele durante a agregação.

    • Linhas sem valor são ignoradas caso nenhum parâmetro Missing seja definido.

    • Ao definir Missing, o sistema utiliza o valor informado como substituto para linhas vazias.

  • Exemplo

    /**
     * The price of each product is listed in the product table. Query the minimum price of the products that are produced in Zhejiang. 
     * Equivalent SQL statement: SELECT min(column_price) FROM product where place_of_production="Zhejiang";
     */
    func min(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.TermQuery{"place_of_production", "Zhejiang"}).
                SetLimit(0). // If you want to obtain only the aggregation results instead of specific data, you can set limit to 0 to improve query performance. 
                Aggregation(search.NewMinAggregation("min_agg_1", "column_price").Missing(0.00)))
    
        searchResponse, err := client.Search(searchRequest) // Execute the statement. 
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        agg1, err := aggResults.Min("min_agg_1") // Obtain the results of the aggregation operation named min_agg_1. 
        if err != nil {
            panic(err)
        }
        if agg1.HasValue() { // Check whether the results of the aggregation operation named min_agg_1 contain values. 
            fmt.Println(agg1.Value) // Display the aggregation results. 
        }
    }

Valor máximo

Obtém o maior valor presente em um campo. Equivale ao uso da função MAX em SQL.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Identificador único da agregação. Necessário para extrair o resultado correspondente posteriormente.

    FieldName

    Define o campo sobre o qual a agregação será executada. Suporta exclusivamente LONG, DOUBLE e DATE.

    Missing

    Especifica um valor substituto para linhas onde o campo alvo está vazio.

    • A ausência deste parâmetro faz com que linhas sem valor sejam descartadas do cálculo.

    • Se preenchido, o valor informado substitui os campos nulos durante o processamento.

  • Exemplo

    /**
     * The price of each product is listed in the product table. Query the maximum price of the products that are produced in Zhejiang. 
     * Equivalent SQL statement: SELECT max(column_price) FROM product where place_of_production = "Zhejiang Province". 
     */
    func max(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.TermQuery{"place_of_production", "Zhejiang"}).
                SetLimit(0). // If you want to obtain only the aggregation results instead of specific data, you can set limit to 0 to improve query performance. 
                Aggregation(search.NewMaxAggregation("max_agg_1", "column_price").Missing(0.00)))
    
        searchResponse, err := client.Search(searchRequest) // Execute the statement. 
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        agg1, err := aggResults.Max("max_agg_1") // Obtain the results of the aggregation operation named max_agg_1. 
        if err != nil {
            panic(err)
        }
        if agg1.HasValue() { // Check whether the results of the aggregation operation named max_agg_1 contain values. 
            fmt.Println(agg1.Value) // Display the aggregation results. 
        }
    }

Soma

Calcula o somatório de todos os valores existentes em um campo numérico. Similar à função SUM do SQL.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Rótulo único para identificar esta operação de agregação nos resultados.

    FieldName

    Nome do campo numérico a ser somado. Restrito aos tipos LONG e DOUBLE.

    Missing

    Valor de fallback aplicado a linhas com campo vazio durante o cálculo da soma.

    • Sem essa configuração, linhas com valores ausentes não participam da soma.

    • Quando configurado, substitui valores nulos pelo número especificado.

  • Exemplo

    /**
     * The sales of each product are listed in the product table. Query the total number of the sold products that are produced in Zhejiang. If the sales of a product are empty, 10 is used as the default value. 
     * Equivalent SQL statement: SELECT sum(column_price) FROM product where place_of_production = "Zhejiang". 
     */
    func sum(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.TermQuery{"place_of_production", "Zhejiang"}).
                SetLimit(0). // If you want to obtain only the aggregation results instead of specific data, you can set limit to 0 to improve query performance. 
                Aggregation(search.NewSumAggregation("sum_agg_1", "column_price").Missing(0.00)))
    
        searchResponse, err := client.Search(searchRequest) // Execute the statement. 
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        agg1, err := aggResults.Sum("sum_agg_1")  // Obtain the results of the aggregation operation named sum_agg_1. 
        if err != nil {
            panic(err)
        }
        fmt.Println(agg1.Value) // Display the aggregation results. 
    }

Valor médio

Determina a média aritmética dos valores de um campo numérico. Corresponde à função AVG do SQL.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Nome distintivo da agregação, usado para acessar seu resultado específico.

    FieldName

    Campo utilizado para calcular a média. Compatível com LONG, DOUBLE e DATE.

    Missing

    Substitui valores vazios nas linhas processadas pelo valor padrão indicado.

    • Se omitido, registros sem valor no campo são excluídos do cálculo da média.

    • Quando presente, assume o valor definido para compor a média nas linhas afetadas.

  • Exemplo

    /**
     * The sales of each product are listed in the product table. Query the average price of the products that are produced in Zhejiang. 
     * EquivalentSQL statement: SELECT avg(column_price) FROM product where place_of_production = "Zhejiang Province". 
     */
    func avg(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.TermQuery{"place_of_production", "Zhejiang"}).
                SetLimit(0). // If you want to obtain only the aggregation results instead of specific data, you can set limit to 0 to improve query performance. 
                Aggregation(search.NewAvgAggregation("avg_agg_1", "column_price").Missing(0.00)))
    
        searchResponse, err := client.Search(searchRequest) // Execute the statement. 
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        agg1, err := aggResults.Avg("avg_agg_1")  // Obtain the results of the aggregation operation named avg_agg_1. 
        if err != nil {
            panic(err)
        }
        if agg1.HasValue() {  // Check whether the results of the aggregation operation named agg1 contain values. 
            fmt.Println(agg1.Value) // Display the aggregation results. 
        }
    }

Contagem

Devolve o total de valores de um determinado campo ou o número total de linhas em um índice de busca. Funciona como a função COUNT do SQL.

Nota

Você pode usar os seguintes métodos para consultar o número total de linhas em um índice de busca ou o número total de linhas que atendem às condições de consulta:

  • Utilize o recurso de contagem da agregação especificando count(*) na requisição.

  • Ative setGetTotalCount como true na consulta para receber a contagem de linhas correspondentes. Para o total absoluto do índice, utilize MatchAllQuery.

Também é possível usar o nome de uma coluna como expressão de contagem para saber quantas linhas possuem aquela coluna específica no índice. Essa técnica é particularmente útil em cenários com colunas esparsas.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Identificador exclusivo da operação de agregação, necessário para recuperar seus resultados.

    FieldName

    Campo alvo da contagem. Tipos suportados: LONG, DOUBLE, BOOLEAN, KEYWORD, GEO_POINT e DATE.

  • Exemplo

    /**
     * Penalty records of merchants are recorded in the merchant table. You can query the number of merchants who are located in Zhejiang and for whom penalty records exist. If no penalty record exists for a merchant, the field that corresponds to penalty records also does not exist for the merchant. 
     * EquivalentSQL statement: SELECT count(column_history) FROM product where place_of_production = "Zhejiang Province". 
     */
    func count(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.TermQuery{"place_of_production", "Zhejiang"}).
                SetLimit(0). // If you want to obtain only the aggregation results instead of specific data, you can set limit to 0 to improve query performance. 
                Aggregation(search.NewCountAggregation("count_agg_1", "column_price")))
    
        searchResponse, err := client.Search(searchRequest) // Execute the statement. 
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        agg1, err := aggResults.Count("count_agg_1") // Obtain the results of the aggregation operation named count_agg_1. 
        if err != nil {
            panic(err)
        }
        fmt.Println(agg1.Value) // Display the aggregation results. 
    }

Contagem distinta

Fornece a quantidade de valores únicos em um campo. Equivalente à função COUNT(DISTINCT) do SQL.

Nota

O resultado da contagem distinta é uma aproximação estatística.

  • Para conjuntos menores que 10.000 linhas, o valor retornado tende a ser exato.

  • Em volumes iguais ou superiores a 100 milhões de linhas, a margem de erro gira em torno de 2%.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Nome singular da operação de agregação para referência posterior nos resultados.

    FieldName

    Campo onde a contagem distinta será aplicada. Aceita LONG, DOUBLE, BOOLEAN, KEYWORD, GEO_POINT e DATE.

    Missing

    Define como tratar linhas com valores ausentes no campo agregado.

    • A omissão deste parâmetro ignora as linhas vazias.

    • Ao defini-lo, o valor serve como substituto para os campos nulos.

  • Exemplo

    /**
     * Query the number of distinct provinces from which the products are produced. 
     * EquivalentSQL statement: SELECT count(distinct column_place) FROM product. 
     */
    func distinctCount(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.TermQuery{"place_of_production", "Zhejiang"}).
                SetLimit(0). // If you want to obtain only the aggregation results instead of specific data, you can set limit to 0 to improve query performance. 
                Aggregation(search.NewDistinctCountAggregation("distinct_count_agg_1", "column_price").Missing(0.00)))
    
        searchResponse, err := client.Search(searchRequest) // Execute the statement. 
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        agg1, err := aggResults.DistinctCount("distinct_count_agg_1") // Obtain the results of the aggregation operation named distinct_count_agg_1. 
        if err != nil {
            panic(err)
        }
        fmt.Println(agg1.Value) // Display the aggregation results. 
    }

Agrupamento por valor de campo

Segmenta os resultados da consulta conforme os valores de um campo. Registros com valores idênticos pertencem ao mesmo grupo. A resposta inclui o valor representativo e a contagem de itens por grupo.

Nota

Em grupos com cardinalidade muito elevada, o número calculado pode apresentar discrepâncias em relação ao valor real.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Identificação única da operação de agrupamento para extração dos resultados.

    FieldName

    Campo base para o agrupamento. Tipos aceitos: LONG, DOUBLE, BOOLEAN, KEYWORD e DATE.

    Size

    Quantidade máxima de grupos retornados. Padrão: 10. Limite superior: 2000. Caso existam mais grupos, apenas os 2.000 primeiros serão exibidos.

    GroupBySorters

    Critérios de ordenação dos grupos. Por padrão, a ordem é decrescente. Múltiplas regras seguem a sequência de configuração. Opções disponíveis:

    • Ordem alfabética crescente pelo valor.

    • Ordem alfabética decrescente pelo valor.

    • Contagem de linhas em ordem ascendente.

    • Contagem de linhas em ordem descendente.

    • Valores de subagregações em ordem ascendente.

    • Valores de subagregações em ordem descendente.

    SubAggregation e SubGroupBy

    Operações adicionais aplicadas sobre cada grupo resultante.

    • Cenário

      Listar a quantidade de produtos por categoria, juntamente com o preço máximo e mínimo de cada uma.

    • Abordagem

      Agrupe pela categoria do produto para obter as contagens. Em seguida, aplique duas subagregações para extrair os preços extremos (máximo e mínimo) dentro de cada grupo.

    • Resultados esperados

      • Frutas: 5 itens. Preço máximo: 15. Preço mínimo: 3.

      • Higiene pessoal: 10 itens. Preço máximo: 98. Preço mínimo: 1.

      • Eletrônicos: 3 itens. Preço máximo: 8.699. Preço mínimo: 2.300.

      • Outros: 15 itens. Preço máximo: 1.000. Preço mínimo: 80.

  • Exemplo

    /**
     * Query the number of products, and the maximum and minimum product prices in each category. 
     * Example of returned results: Fruits: 5. The maximum value of the price is 15, and the minimum value of the price is 3. Toiletries: 10. The maximum value of the price is 98, and the minimum value of the price is 1. Electronic devices: 3. The maximum value of the price is 8699, and the minimum value of the price is 2300. 
     * Other products: 15. The maximum value of the price is 1000, and the minimum value of the price is 80. 
     */
    func GroupByField(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}). // Match all rows. 
                SetLimit(0).
                GroupBy(search.NewGroupByField("group1", "column_type"). // Group products by category. 
                    SubAggregation(search.NewMinAggregation("min_price", "column_price")). // Query the minimum prices in each category. 
                    SubAggregation(search.NewMaxAggregation("max_price", "column_price")))) // Query the maximum prices in each category. 
    
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        groupByResults := searchResponse.GroupByResults // Obtain the aggregation results. 
        group, err := groupByResults.GroupByField("group1")
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
    
        for _, item := range group.Items { // Traverse the groups that are returned. 
            // Display the value of each group and the number of rows in each group. 
            fmt.Println("\tkey: ", item.Key, ", rowCount: ", item.RowCount) 
    
            // Display the lowest prices. 
            minPrice, _ := item.SubAggregations.Min("min_price")
            if minPrice.HasValue() {
                fmt.Println("\t\tmin_price: ", minPrice.Value)
            }
    
            // Display the highest prices. 
            maxPrice, _ := item.SubAggregations.Max("max_price")
            if maxPrice.HasValue() {
                fmt.Println("\t\tmax_price: ", maxPrice.Value)
            }
        }
    }

Agrupamento por múltiplos campos

O método de agregação que pode ser usado para agrupar resultados de consulta com base em múltiplos campos. Você pode usar tokens para realizar paginação.

Nota

Para agrupamentos multifacetados, opte pelo modo aninhado do parâmetro groupBy ou utilize GroupByComposite. Consulte Apêndice: Diferenças entre métodos de agrupamento por múltiplos campos para comparar as abordagens.

  • Parâmetros

    Parâmetro

    Descrição

    GroupByName

    Nome exclusivo para identificar a operação de agregação e recuperar seus resultados.

    SourceGroupByList

    Lista de campos para compor o agrupamento. É possível combinar até 32 campos e aplicar agregações sobre eles. Tipos de grupo suportados:

    Importante
    • Nos tipos definidos em SourceGroupByList, o parâmetro GroupBySorter aceita apenas groupKeySort.

    • A ordenação padrão dos grupos é decrescente.

    • Campos inexistentes em uma linha retornam NULL.

    • GroupByField permite configurar apenas: GroupByName, FieldName e GroupBySorter.

    • GroupByHistogram restringe-se a: GroupByName, FieldName, Interval e GroupBySorter.

    • GroupByDateHistogram aceita somente: GroupByName, FieldName, Interval, TimeZone e GroupBySorter.

    NextToken

    Token de paginação para solicitar a próxima página de grupos. Obtido via GroupByCompositeResult, garante a recuperação completa dos resultados de agrupamento.

    Size

    Define o tamanho da página de grupos. Se houver mais grupos que o Size, utilize NextToken para navegar.

    Importante

    Os parâmetros Size e SuggestedSize são mutuamente exclusivos. Na maioria dos casos, prefira Size.

    Use SuggestedSize ao integrar o Tablestore com engines de alta vazão como Apache Spark ou PrestoSQL.

    SuggestedSize

    Tamanho sugerido para a página de grupos. Aceita valores maiores que o limite do servidor ou -1. O servidor ajustará o retorno conforme sua capacidade. Ideal para integração com processadores massivos (Spark, PrestoSQL).

    Valores excessivos são limitados automaticamente pelo servidor. O retorno efetivo segue a lógica: min(suggestedSize, limite do servidor, total de grupos).

    SubAggList e SubGroupByList

    Definem subagregações a serem executadas sobre os grupos formados.

    Importante

    O tipo GroupByComposite não é permitido dentro de SubGroupByList.

  • Exemplo

    /**
     * Group and aggregate query results: Group the query results and perform the aggregation operation on the resulting groups based on the parameters such as groupbyField, groupByHistogram, and groupByDataHistogram that are passed to the SourceGroupBy parameter.
     * Return the aggregated results of multiple fields in a flat structure. 
     */
    func GroupByComposite(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
        searchRequest.
            SetTableName(tableName).
            SetIndexName(indexName).
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}).
                SetLimit(0).
                GroupBy(search.NewGroupByComposite("groupByComposite").
                SourceGroupBys(search.NewGroupByField("groupByColLong", "Col_Long"),
                    search.NewGroupByField("groupByColKeyword", "Col_Keyword"),
                    search.NewGroupByField("groupByColDouble", "Col_Double")).
                SetSize(100)))
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v\n", err)
            return
        }
    
        for {
            if searchResponse.GroupByResults.Empty() {
                return
            }
    
            groupByResults := searchResponse.GroupByResults
            group, err := groupByResults.GroupByComposite("groupByComposite")
            if err != nil {
                fmt.Printf("%#v\n", err)
                return
            }
    
            if group == nil {
                return
            }
    
            for _, item := range group.Items {    // Traverse the groups that are returned. 
                // Display the value of each group and the number of rows in each group. 
                if item.Keys != nil {
                    for i := 0; i < len(item.Keys); i++ {
                        if item.Keys[i] == nil {
                            fmt.Printf(" null ")
                        } else {
                            fmt.Printf(" %v ", *item.Keys[i])
                        }
    
                    }
                    fmt.Printf("\trowCount:%v\n", item.RowCount)
                }
            }
    
            if group.NextToken != nil {
                searchRequest.
                    SetTableName(tableName).
                    SetIndexName(indexName).
                    SetSearchQuery(search.NewSearchQuery().
                        SetQuery(&search.MatchAllQuery{}).
                        SetLimit(0).
                        GroupBy(search.NewGroupByComposite("groupByComposite").
                            SourceGroupBys(search.NewGroupByField("groupByColLong", "Col_Long"),
                                search.NewGroupByField("groupByColKeyword", "Col_Keyword"),
                                search.NewGroupByField("groupByColDouble", "Col_Double")).
                            SetSize(100).
                            SetNextToken(group.NextToken)))
    
                searchResponse, err = client.Search(searchRequest)
                if err != nil {
                    fmt.Printf("%#v\n", err)
                    return
                }
            } else {
                break
            }
        }
    }

Agrupamento por intervalo

O método de agregação que pode ser usado para agrupar resultados de consulta com base nos intervalos de valores de um campo. Os valores de campo que estão dentro de um intervalo específico são agrupados. O número de valores em cada intervalo é retornado.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Rótulo exclusivo da operação de agregação para identificação nos resultados.

    FieldName

    Campo numérico base para os intervalos. Suporta LONG e DOUBLE.

    Range(fromInclusive float64, toExclusive float64)

    Define os limites do intervalo de agrupamento.

    Aceita NegInf como início e Inf como fim.

    SubAggregation e SubGroupBy

    Permite aplicar novas agregações ou agrupamentos sobre os resultados de cada intervalo.

    Exemplo: após agrupar vendas por faixa de valor e por província, use GroupByField dentro do GroupByRange para descobrir qual província domina uma determinada faixa de vendas.

  • Exemplo

    /**
     * Group sales volumes based on ranges [NegInf, 1000), [1000, 5000), and [5000, Inf) to obtain the sales volume in each range. 
     */
    func GroupByRange(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}). // Match all rows. 
                SetLimit(0).
                GroupBy(search.NewGroupByRange("group1", "column_number").
                    Range(search.NegInf, 1000).
                    Range(1000, 5000).
                    Range(5000, search.Inf)))
    
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        groupByResults := searchResponse.GroupByResults // Obtain the aggregation results. 
        group, err := groupByResults.GroupByRange("group1")
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        for _, item := range group.Items { // Traverse the groups that are returned. 
            fmt.Println("\t[", item.From, ", ", item.To, "), rowCount: ", item.RowCount) // Display the number of rows in each group. 
        }
    }

Agrupamento por localização geográfica

Organiza os resultados em anéis de distância a partir de um ponto central. Itens situados dentro de determinadas faixas de distância são agrupados, retornando a contagem por intervalo.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Nome único da operação de agregação.

    FieldName

    Campo geográfico utilizado no cálculo. Deve ser do tipo GEO_POINT.

    CenterPoint(latitude float64, longitude float64)

    Coordenadas do ponto de referência.

    latitude define a latitude e longitude define a longitude do centro.

    Range(fromInclusive float64, toExclusive float64)

    Faixas de distância para formação dos grupos, medidas em metros.

    Suporta NegInf e Inf como limites.

    SubAggregation e SubGroupBy

    Possibilita executar operações adicionais sobre os grupos de distância formados.

  • Exemplo

    
    /**
     * Group users based on the distance from their geographical locations to a Wanda Plaza to obtain the number of users in each distance range. The distance ranges are [NegInf, 1000), [1000, 5000), and [5000, Inf). Unit: meters. 
     */
    func GroupByGeoDistance(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}). // Match all rows. 
                SetLimit(0).
                GroupBy(search.NewGroupByGeoDistance("group1", "Col_GeoPoint", search.GeoPoint{Lat: 30.137817, Lon:120.08681}).
                    Range(search.NegInf, 1000).
                    Range(1000, 5000).
                    Range(5000, search.Inf)))
    
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        groupByResults := searchResponse.GroupByResults // Obtain the aggregation results. 
        group, err := groupByResults.GroupByGeoDistance("group1")
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        for _, item := range group.Items { // Traverse the groups that are returned. 
            fmt.Println("\t[", item.From, ", ", item.To, "), rowCount: ", item.RowCount) // Display the number of rows in each group. 
        }
    }

Agrupamento por filtro

Aplica condições de filtragem aos resultados e conta quantos itens atendem a cada critério. A resposta respeita a ordem de definição dos filtros.

  • Parâmetros

    Parâmetro

    Descrição

    Name

    Identificador exclusivo da operação de agregação.

    Query

    Condições de filtro aplicadas. Os resultados seguem a ordem destas condições.

    SubAggregation e SubGroupBy

    Operações secundárias executadas sobre os conjuntos filtrados.

  • Exemplo

    /**
     * Specify the following filters to obtain the number of items that match each filter: The sales exceed 100, the place of origin is Zhejiang, and the description contains Hangzhou. 
     */
    func GroupByFilter(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}). // Match all rows. 
                SetLimit(0).
                GroupBy(search.NewGroupByFilter("group1").
                    Query(&search.RangeQuery{
                        FieldName: "number",
                        From: 100,
                        IncludeLower: true}).
                    Query(&search.TermQuery{
                        FieldName: "place",
                        Term:      "Zhejiang",
                    }).
                    Query(&search.MatchQuery{
                        FieldName: "description",
                        Text: "Hangzhou",
                    })))
    
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        groupByResults := searchResponse.GroupByResults // Obtain the aggregation results. 
        group, err := groupByResults.GroupByFilter("group1")
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        for _, item := range group.Items { // Traverse the groups that are returned. 
            fmt.Println("\trowCount: ", item.RowCount) // Display the number of rows in each group. 
        }
    }

Agrupamento por histograma

Distribui os resultados em intervalos numéricos regulares. Valores contidos na mesma faixa são agrupados, retornando o intervalo e a respectiva contagem.

  • Parâmetros

    Parâmetro

    Descrição

    GroupByName

    Nome único para referenciar os resultados desta agregação.

    Field

    Campo alvo da agregação. Apenas LONG e DOUBLE são permitidos.

    Interval

    Tamanho do intervalo numérico para segmentação dos dados.

    FieldRange[min,max]

    Limites do campo que, combinados com Interval, restringem o número de grupos. O cálculo (FieldRange.max-FieldRange.min)/interval não pode ultrapassar 2000.

    MinDocCount

    Limiar mínimo de documentos. Grupos com menos linhas que este valor são omitidos nos resultados.

    Missing

    Valor substituto para linhas onde o campo está vazio.

    • Se não definido, linhas vazias são ignoradas.

    • Se definido, o valor preenche as lacunas nas linhas afetadas.

  • Exemplo

    func GroupByHistogram(client *tablestore.TableStoreClient, tableName string, indexName string) {
    	searchRequest := &tablestore.SearchRequest{}
    	searchRequest.
    		request.setTableName(tableName); // Specify the name of the data table. 
    		request.setIndexName(indexName); // Specify the name of the search index. 
    		SetSearchQuery(search.NewSearchQuery().
    			SetQuery(&search.MatchAllQuery{}). // Match all rows. 
    			SetLimit(0).
    			GroupBy(search.NewGroupByHistogram("group1", "field_name").
    				SetMinDocCount(1).
    				SetFiledRange(1, 100).
    				SetMissing(3).
    				SetInterval(10)))
    
    	searchResponse, err := client.Search(searchRequest)
    	if err != nil {
    		fmt.Printf("%#v", err)
    		return
    	}
    	groupByResults := searchResponse.GroupByResults    // Obtain the aggregate results. 
    	group, err := groupByResults.GroupByHistogram("group1")
    	if err != nil {
    		fmt.Printf("%#v", err)
    		return
    	}
    	for _, item := range group.Items {    // Traverse the groups that are returned. 
    		fmt.Println("key:", item.Key.Value, ", rowCount:", item.Value)
    	}
    }

Agrupamento por histograma de datas

Segmenta resultados com base em intervalos temporais fixos. Registros dentro do mesmo período formam um grupo, retornando o intervalo e a contagem de itens.

  • Parâmetros

    Parâmetro

    Descrição

    GroupByName

    Identificador único da operação de agregação temporal.

    Field

    Campo de data utilizado para o agrupamento. Exclusivo para o tipo DATE.

    Interval

    Duração de cada intervalo temporal para agregação.

    FieldRange[min,max]

    Janela temporal que, junto com Interval, limita a quantidade de grupos. A fórmula (FieldRange.max-FieldRange.min)/interval tem teto de 2000.

    MinDocCount

    Número mínimo de linhas exigido. Grupos abaixo deste limiar não aparecem no resultado.

    Missing

    Valor de data padrão para linhas com campo vazio.

    • Sem este parâmetro, linhas sem data são descartadas.

    • Com este parâmetro, a data informada substitui os valores nulos.

    TimeZone

    Fuso horário no formato +hh:mm ou -hh:mm, como +08:00 ou -09:00. Obrigatório apenas para campos DATE.

    Evita desvios de horas nos resultados de agregação de datas quando especificado corretamente.

  • Exemplo

    func GroupByDateHistogram(client *tablestore.TableStoreClient, tableName string, indexName string) {
    	searchRequest := &tablestore.SearchRequest{}
    	searchRequest.
    		request.setTableName(tableName); // Specify the name of the data table. 
    		request.setIndexName(indexName); // Specify the name of the search index. 
    		SetSearchQuery(search.NewSearchQuery().
    			SetQuery(&search.MatchAllQuery{}). // Match all rows. 
    			SetLimit(0).
    			GroupBy(search.NewGroupByDateHistogram("date_group", "date_field_name").
    				SetMinDocCount(1).
    				SetFiledRange("2017-05-01 10:00", "2017-05-21 13:00:00").
    				SetMissing("2017-05-01 13:01:00").
    				SetInterval(model.DateTimeValue{
    					Value: proto.Int32(1),
    					Unit:  model.DateTimeUnit_DAY.Enum(),
    				})))
    
    	searchResponse, err := client.Search(searchRequest)
    	if err != nil {
    		fmt.Printf("%#v", err)
    		return
    	}
    	groupByResults := searchResponse.GroupByResults    // Obtain the aggregate results. 
    	group, err := groupByResults.GroupByDateHistogram("date_group")
    	if err != nil {
    		fmt.Printf("%#v", err)
    		return
    	}
    
    	for _, item := range group.Items {    // Traverse the groups that are returned. 
    		fmt.Printf("millisecondTimestamp:%d , rowCount:%d \n", item.Timestamp, item.RowCount)
    	}
    }

Aninhamento

O aninhamento permite encadear subagregações dentro de grupos. Veja exemplos de estruturas com dois níveis:

  • GroupBy + SubGroupBy: Agrupamento hierárquico por província e depois por cidade, detalhando os dados municipais dentro de cada estado.

  • GroupBy + SubAggregation: Agrupamento por província seguido de uma agregação métrica (ex: valor máximo) para cada região.

Nota

Para garantir performance e estabilidade, existe um limite máximo de níveis de aninhamento. Consulte Limites do índice de busca.

Exemplo

/**
 * Perform nesting-based aggregation. 
 * Two aggregations and one GroupByRange attribute are specified in the outermost level of GroupByField. 
 */
func NestedSample(client *tablestore.TableStoreClient, tableName string, indexName string) {
    searchRequest := &tablestore.SearchRequest{}

    searchRequest.
        SetTableName(tableName). // Specify the name of the data table. 
        SetIndexName(indexName). // Specify the name of the search index. 
        SetSearchQuery(search.NewSearchQuery().
            SetQuery(&search.MatchAllQuery{}). // Match all rows. 
            SetLimit(0).
            GroupBy(search.NewGroupByField("group1", "field1").
                SubAggregation(search.NewMinAggregation("sub_agg1", "sub_field1")).
                SubAggregation(search.NewMaxAggregation("sub_agg2", "sub_field2")).
                SubGroupBy(search.NewGroupByRange("sub_group1", "sub_field3").
                    Range(search.NegInf, 3).
                    Range(3, 5).
                    Range(5, search.Inf))))

    searchResponse, err := client.Search(searchRequest)
    if err != nil {
        fmt.Printf("%#v", err)
        return
    }
    groupByResults := searchResponse.GroupByResults // Obtain the aggregation results. 
    group, err := groupByResults.GroupByField("group1")
    if err != nil {
        fmt.Printf("%#v", err)
        return
    }

    for _, item := range group.Items { // Traverse the groups that are returned. 
        // Display the value of each group and the number of rows in each group. 
        fmt.Println("\tkey: ", item.Key, ", rowCount: ", item.RowCount) 

        // Obtain the results of the aggregation operation named sub_agg1. 
        subAgg1, _ := item.SubAggregations.Min("sub_agg1")
        if subAgg1.HasValue() {
            fmt.Println("\t\tsub_agg1: ", subAgg1.Value)
        }

        // Obtain the results of the aggregation operation named sub_agg2. 
        subAgg2, _ := item.SubAggregations.Max("sub_agg2")
        if subAgg2.HasValue() {
            fmt.Println("\t\tsub_agg2: ", subAgg2.Value)
        }

        // Obtain the results of the aggregation operation named sub_group1. 
        subGroup, _ := item.SubGroupBys.GroupByRange("sub_group1")
        for _, item := range subGroup.Items {
            fmt.Println("\t\t[", item.From, ", ", item.To, "), rowCount: ", item.RowCount)
        }
    }
}

Múltiplas agregações

Combine diferentes operações de agregação em uma única consulta.

Nota

Consultas com muitas agregações complexas simultâneas podem apresentar latência elevada.

  • Exemplo 1

    func MultipleAggregations(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}). // Match all rows. 
                SetLimit(0).
                Aggregation(search.NewAvgAggregation("agg1", "Col_Long")). // Calculate the average value of the Col_Long field. 
                Aggregation(search.NewDistinctCountAggregation("agg2", "Col_Long")). // Calculate the number of distinct values of the Col_Long field. 
                Aggregation(search.NewMaxAggregation("agg3", "Col_Long")). // Query the maximum value of the Col_Long field. 
                Aggregation(search.NewSumAggregation("agg4", "Col_Long")). // Calculate the sum of values of the Col_Long field. 
                Aggregation(search.NewCountAggregation("agg5", "Col_Long"))) // Calculate the number of rows that contain the Col_Long field. 
    
        // Return all columns. 
        searchRequest.SetColumnsToGet(&tablestore.ColumnsToGet{
            ReturnAll: true,
        })
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
    
        // Obtain the average value obtained from the aggregation operation. 
        agg1, err := aggResults.Avg("agg1") // Obtain the results of the aggregation operation named agg1. 
        if err != nil {
            panic(err)
        }
        if agg1.HasValue() { // Check whether the results of the aggregation operation named agg1 contain values. 
            fmt.Println("(avg) agg1: ", agg1.Value) // Display the average value of the Col_Long field. 
        } else {
            fmt.Println("(avg) agg1: no value") // Display the rows that contain no values for the Col_Long field. 
        }
    
        // Obtain the number of distinct values from the results of the aggregation operation. 
        agg2, err := aggResults.DistinctCount("agg2") // Obtain the results of the aggregation operation named agg2. 
        if err != nil {
            panic(err)
        }
        fmt.Println("(distinct) agg2: ", agg2.Value) // Display the number of distinct values for the Col_Long field. 
    
        // Display the maximum value obtained from the aggregation operation. 
        agg3, err := aggResults.Max("agg3") // Obtain the results of the aggregation operation named agg3. 
        if err != nil {
            panic(err)
        }
        if agg3.HasValue() {
            fmt.Println("(max) agg3: ", agg3.Value) // Display the maximum value for the Col_Long field. 
        } else {
            fmt.Println("(max) agg3: no value") // Display the rows that contain no values for the Col_Long field. 
        }
    
        // Obtain the sum from the results of the aggregation operation. 
        agg4, err := aggResults.Sum("agg4") // Obtain the results of the aggregation operation named agg4. 
        if err != nil {
            panic(err)
        }
        fmt.Println("(sum) agg4: ", agg4.Value) // Display the sum for the Col_Long field. 
    
        // Obtain the number of rows from the results of the aggregation operation. 
        agg5, err := aggResults.Count("agg5") // Obtain the results of the aggregation operation named agg5. 
        if err != nil {
            panic(err)
        }
        fmt.Println("(count) agg6: ", agg5.Value) // Display the number of values for the Col_Long field. 
    }
  • Exemplo 2

    func MultipleAggregationsAndGroupBysSample(client *tablestore.TableStoreClient, tableName string, indexName string) {
        searchRequest := &tablestore.SearchRequest{}
    
        searchRequest.
            SetTableName(tableName). // Specify the name of the data table. 
            SetIndexName(indexName). // Specify the name of the search index. 
            SetSearchQuery(search.NewSearchQuery().
                SetQuery(&search.MatchAllQuery{}). // Match all rows. 
                SetLimit(0).
                Aggregation(search.NewAvgAggregation("agg1", "Col_Long")). // Calculate the average value of the Col_Long field. 
                Aggregation(search.NewDistinctCountAggregation("agg2", "Col_Long")). // Calculate the number of distinct values of the Col_Long field. 
                Aggregation(search.NewMaxAggregation("agg3", "Col_Long")). // Query the maximum value of the Col_Long field. 
                GroupBy(search.NewGroupByField("group1", "Col_Keyword"). // Group the rows by field value based on the Col_Keyword field. 
                    GroupBySorters([]search.GroupBySorter{}). // Specify the method that is used to sort the groups that are returned. 
                    Size(2). // Specify that only the first two groups are returned. 
                    SubAggregation(search.NewAvgAggregation("sub_agg1", "Col_Long")). // Perform sub-aggregation operations on each group. 
                    SubGroupBy(search.NewGroupByField("sub_group1", "Col_Keyword2"))). // Perform sub-aggregation operations on each group. 
                GroupBy(search.NewGroupByRange("group2", "Col_Long"). // Group the rows by range based on the Col_Long field. 
                    Range(search.NegInf, 3). // The first group contains rows whose values in the Col_Long field are within the (NegInf, 3) range. 
                    Range(3, 5). // The second group contains rows whose values in the Col_Long field are within the [3, 5) range. 
                    Range(5, search.Inf))) // The third group contains rows whose values in the Col_Long field are within the [5, Inf) range. 
    
        // Return all columns. 
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
    
        aggResults := searchResponse.AggregationResults // Obtain the aggregation results. 
        // Obtain the average value obtained from the aggregation operation. 
        agg1, err := aggResults.Avg("agg1") // Obtain the results of the aggregation operation named agg1. 
        if err != nil {
            panic(err)
        }
        if agg1.HasValue() { // Check whether the results of the aggregation operation named agg1 contain values. 
            fmt.Println("(avg) agg1: ", agg1.Value) // Display the average value of the Col_Long field. 
        } else {
            fmt.Println("(avg) agg1: no value") // Display the rows that contain no values for the Col_Long field. 
        }
    
        // Obtain the number of distinct values from the results of the aggregation operation. 
        agg2, err := aggResults.DistinctCount("agg2") // Obtain the results of the aggregation operation named agg2. 
        if err != nil {
            panic(err)
        }
        fmt.Println("(distinct) agg2: ", agg2.Value) // Display the number of distinct values for the Col_Long field. 
    
        // Display the maximum value obtained from the aggregation operation. 
        agg3, err := aggResults.Max("agg3") // Obtain the results of the aggregation operation named agg3. 
        if err != nil {
            panic(err)
        }
        if agg3.HasValue() {
            fmt.Println("(max) agg3: ", agg3.Value) // Display the maximum value for the Col_Long field. 
        } else {
            fmt.Println("(max) agg3: no value") // Display the rows that contain no values for the Col_Long field. 
        }
    
        groupByResults := searchResponse.GroupByResults // Obtain the aggregation results. 
        // Obtain the results of the GroupByField aggregation operation. 
        group1, err := groupByResults.GroupByField("group1") // Obtain the results of the aggregation operation named group1. 
        if err != nil {
            panic(err)
        }
        fmt.Println("group1: ")
        for _, item := range group1.Items { // Traverse all groups that are returned. 
            //item
            fmt.Println("\tkey: ", item.Key, ", rowCount: ", item.RowCount) // Display the number of rows in each group. 
    
            // Obtain the average value obtained from the sub-aggregation operation. 
            subAgg1, err := item.SubAggregations.Avg("sub_agg1") // Obtain the results of the sub-aggregation operation named sub_agg1. 
            if err != nil {
                panic(err)
            }
            if subAgg1.HasValue() { // If sub_agg1 obtains the average value for the Col_Long field, HasValue() is set to true. 
                fmt.Println("\t\tsub_agg1: ", subAgg1.Value) // Display the average value for the Col_Long field obtained from the sub-aggregation operation. 
            }
    
            // Obtain the results of the GroupByField sub-aggregation operation. 
            subGroup1, err := item.SubGroupBys.GroupByField("sub_group1") // Obtain the results of the sub-aggregation operation named sub_group1. 
            if err != nil {
                panic(err)
            }
            fmt.Println("\t\tsub_group1")
            for _, subItem := range subGroup1.Items { // Traverse the results of the sub-aggregation operation named sub_group1. 
                fmt.Println("\t\t\tkey: ", subItem.Key, ", rowCount: ", subItem.RowCount) // Display the number of rows in each group that is obtained from the results of the sub-aggregation operation named sub_group1. 
                tablestore.Assert(subItem.SubAggregations.Empty(), "")
                tablestore.Assert(subItem.SubGroupBys.Empty(), "")
            }
        }
    
        // Obtain the results of the GroupByRange aggregation operation. 
        group2, err := groupByResults.GroupByRange("group2") // Obtain the results of the aggregation operation named group2. 
        if err != nil {
            panic(err)
        }
        fmt.Println("group2: ")
        for _, item := range group2.Items { // Traverse all groups that are returned. 
            fmt.Println("\t[", item.From, ", ", item.To, "), rowCount: ", item.RowCount) // Display the number of rows in each group. 
        }
    }

Apêndice: Diferenças entre métodos de agrupamento por múltiplos campos

Para agrupar por vários campos, você pode optar pelo modo aninhado do parâmetro groupBy ou utilizar GroupByComposite. A tabela abaixo compara essas duas abordagens.

Recurso

groupBy (aninhado)

Agrupamento por múltiplos campos

size

2000

2000

Limites de campos

Suporta até 3 níveis.

Suporta até 32 níveis.

Paginação

Não suportada

Suportada via parâmetro nextToken

Ordenação de linhas nos grupos

  • Alfabética ou alfabética inversa

  • Por contagem de linhas (ascendente ou descendente)

  • Por valores de subagregação (ascendente ou descendente)

Alfabética ou alfabética inversa

Suporte a agregação

Sim

Sim

Compatibilidade

Campos Date retornam resultados no formato especificado.

Campos DATE retornam strings de timestamp.