Агрегатные функции

Reindexer поддерживает агрегатные функции для более гибкого поиска:

Агрегатная функция для SQL Агрегатная функция для GO Описание
MAX() AggregateMax Получить максимальное значение в столбце
MIN() AggregateMin Получить минимальное значение в столбце
AVG() AggregateAvg Получить среднее значение в столбце
SUM() AggregateSum Получить сумму значений элементов в столбце
COUNT() ReqTotal Получить общее количество элементов, удовлетворяющих условиям выборки
COUNT_CACHED() CachedTotal То же, что COUNT, но с использованием кэшированного значения. Может быть более эффективно, чем COUNT для последовательных запросов, отличающихся только значениями LIMIT/OFFSET
DISTINCT() Distinct Получить записи с уникальными значениями
FACET() AggregateFacet Получить уникальные записи в неймспейсе с указанием количества

Фасеты агрегации (фильтры) могут применяться к нескольким столбцам. Результат может быть отсортирован по любому столбцу и ограничен с помощью Limit и Offset.

Если было задано более одного оператора DISTINCT, в выборку попадет пересечение множеств уникальных полей. То есть будут выбраны только те записи, для которых уникальные значения всех указанных полей были найдены в первую очередь. Например, если сперва была найдена запись со значениями полей { year: "2019", name: "Motherless Brooklyn" }, а затем { year: "2019", name: "Joker" }, в выборку попадет только первая запись.

В Go-коннекторе подсчёта общего количества записей, удовлетворяющих условиям, в запросе используются методы ReqTotal() и CachedTotal(). Результат вычисления в обоих случаях может быть получен при помощи вызова метода TotalCount() у возвращённого из запроса итератора.

Примеры:

Агрегатные функции должны быть вызваны перед выполнением запроса.

В Go для поддержки фасетов агрегации реализован метод AggregateFacet, возвращающий AggregationFacetRequest, который имеет методы Sort, Limit и Offset.

  query := db.Query("test_table")
  query.AggregateMax("price")
  query.AggregateFacet("name", "price").Sort("name", true).Sort("count", false).Offset(10).Limit(100).ReqTotal()
  iterator := query.Exec()

  aggMaxRes := iterator.AggResults()[0]
  if aggMaxRes.Value != nil {
    fmt.Printf ("max price = %d\n", *aggMaxRes.Value)
  } else {
    fmt.Prinln ("no data to aggregate")
  }

  aggFacetRes := iterator.AggResults()[1]
  fmt.Printf ("'name' 'price' -> count")
  for _, facet := range aggFacetRes.Facets {
    fmt.Printf ("'%s' '%s' -> %d", facet.Values[0], facet.Values[1], facet.Count)
  }

    ....
  query := db.Query("test_table")
  query.Distinct("name").Distinct("price")
  iterator := query.Exec()

  aggResults := iterator.aggResults()

  distNames := aggResults[0]
  fmt.Println ("names:")
  for _, name := range distNames.Distincts {
    fmt.Println(name)
  }

  distPrices := aggResults[1]
  fmt.Println ("prices:")
  for _, price := range distPrices.Distincts {
    fmt.Println(price)
  }

Функции MIN(), MAX(), AVG() и SUM() могут принимать в качестве аргумента число или строку, которую можно преобразовать в число. Агрегатные функции можно указывать через запятую с разными аргументами.

-- Вывод максимального значения поля
SELECT MAX('field') FROM test_table
-- Вывод количества элементов неймспейса
SELECT COUNT(*) FROM test_table
-- Вывод уникальных значений столбца
SELECT DISTINCT(year) FROM test_table
-- Вывод уникальных пар столбцов
SELECT DISTINCT(year), DISTINCT(name) FROM test_table
-- Вывод уникальных записей в неймспейсе с указанием количества
SELECT facet('name') FROM test_table
# Вывод максимального значения поля
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "test_table",
  "type": "select",
  "aggregations": [
    {
      "fields": [
        "price"
      ],
      "type": "MAX"
    }
  ]
}'
# Вывод уникальных значений столбца
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "test_table",
  "type": "select",
  "aggregations": [
    {
      "fields": [
        "name"
      ],
      "type": "DISTINCT"
    }
  ]
}'
# Вывод уникальных пар столбцов
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "test_table",
  "type": "select",
  "aggregations": [
    {
      "fields": [
        "name"
      ],
      "type": "DISTINCT"
    },
    {
      "fields": [
        "price"
      ],
      "type": "DISTINCT"
    }
  ]
}'
# Вывод уникальных записей в неймспейсе с указанием количества
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "test_table",
  "type": "select",
  "aggregations": [
    {
      "fields": [
        "name"
      ],
      "type": "FACET"
    }
  ]
}'