Spec-Zone.ru › Elasticsearch 7
›Elasticsearch Guide [7.17] ›Агрегирования ›Метрические агрегирования

Агрегирование метрик на основе скриптов

Метрическое агрегирование, которое выполняется с помощью скриптов для вычисления метрики.

Использование скриптов может привести к замедлению скорости поиска. См. Скрипты, кэширование и скорость поиска.

Пример:

POST ledger/_search?size=0
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "profit": {
      "scripted_metric": {
        "init_script": "state.transactions = []", 
        "map_script": "state.transactions.add(doc.type.value == 'sale' ? doc.amount.value : -1 * doc.amount.value)",
        "combine_script": "double profit = 0; for (t in state.transactions) { profit += t } return profit",
        "reduce_script": "double profit = 0; for (a in states) { profit += a } return profit"
      }
    }
  }
}

init_script — это необязательный параметр, все остальные скрипты обязательны.

Приведённое выше агрегирование демонстрирует, как с помощью агрегирования на основе скриптов вычислить общую прибыль от транзакций продаж и затрат.

Результат выполнения вышеуказанного агрегирования:

{
  "took": 218,
  ...
  "aggregations": {
    "profit": {
      "value": 240.0
    }
  }
}

Приведенный выше пример также может быть задан с использованием хранимых скриптов следующим образом:

POST ledger/_search?size=0
{
  "aggs": {
    "profit": {
      "scripted_metric": {
        "init_script": {
          "id": "my_init_script"
        },
        "map_script": {
          "id": "my_map_script"
        },
        "combine_script": {
          "id": "my_combine_script"
        },
        "params": {
          "field": "amount"           
        },
        "reduce_script": {
          "id": "my_reduce_script"
        }
      }
    }
  }
}

Параметры скрипта для init, map и combine скриптов должны быть указаны в глобальном объекте params, чтобы они могли быть объединены между скриптами.

Дополнительные сведения о спецификации скриптов см. в документации по скриптам.

Допустимые типы возвращаемых значений

Несмотря на то, что в одном скрипте можно использовать любой допустимый скриптовый объект, скрипты должны возвращать или хранить в объекте state только следующие типы:

  • примитивные типы
  • Строка
  • Карта (содержащая только ключи и значения перечисленных здесь типов)
  • Массив (содержащий элементы только перечисленных здесь типов)

Область действия скриптов

Агрегирование метрик на основе скриптов использует скрипты на 4 этапах выполнения:

init_script

Выполняется до сбора любых документов. Позволяет агрегации установить начальное состояние.

В приведенном выше примере init_script создает массив transactions в объекте state.

map_script

Выполняется один раз на каждый собранный документ. Это обязательный скрипт. Если не указан combine_script, результат необходимо сохранить в объекте state.

В приведенном выше примере, map_script проверяет значение поля type. Если значение равно sale, значение поля amount добавляется в массив transactions. Если значение поля type не равно sale, отрицательное значение поля amount добавляется в transactions.

combine_script

Выполняется один раз на каждом фрагменте после завершения сбора документов. Это обязательный скрипт. Позволяет агрегации объединить состояние, возвращенное из каждого фрагмента.

В приведенном выше примере, combine_script перебирает все сохраненные транзакции, суммирует значения в переменной profit и, наконец, возвращает profit.

reduce_script

Выполняется один раз на узле координации после того, как все фрагменты вернули свои результаты. Это обязательный скрипт. Скрипт имеет доступ к переменной states, которая является массивом результатов combine_script на каждом фрагменте.

В приведенном выше примере, reduce_script перебирает массив profit, возвращаемый каждым фрагментом, суммирует значения, прежде чем вернуть окончательную комбинированную прибыль, которая будет возвращена в ответе на агрегирование.

Пример работы

Представьте себе ситуацию, когда вы индексируете следующие документы в индекс с 2 фрагментами:

PUT /transactions/_bulk?refresh
{"index":{"_id":1}}
{"type": "sale","amount": 80}
{"index":{"_id":2}}
{"type": "cost","amount": 10}
{"index":{"_id":3}}
{"type": "cost","amount": 30}
{"index":{"_id":4}}
{"type": "sale","amount": 130}

Допустим, что документы 1 и 3 попадают на фрагмент A, а документы 2 и 4 — на фрагмент B. Ниже приведён разбор результата агрегирования на каждом этапе приведенного выше примера.

До выполнения init_script

state инициализируется как новый пустой объект.

"state" : {}

После выполнения init_script

Этот скрипт выполняется один раз на каждом фрагменте перед началом сбора документов, и поэтому у нас будет копия на каждом фрагменте:

Фрагмент A
"state" : {
    "transactions" : []
}
Фрагмент B
"state" : {
    "transactions" : []
}

После выполнения map_script

Каждый фрагмент собирает свои документы и выполняет map_script для каждого собранного документа:

Фрагмент A
"state" : {
    "transactions" : [ 80, -30 ]
}
Фрагмент B
"state" : {
    "transactions" : [ -10, 130 ]
}

После выполнения combine_script

combine_script выполняется на каждом фрагменте после сбора документов и уменьшает все транзакции до одной общей прибыли для каждого фрагмента (суммируя значения в массиве transactions), которая передаётся узлу координации:

Фрагмент A
50
Фрагмент B
120

После выполнения reduce_script

reduce_script получает массив states, содержащий результат combine_script для каждого фрагмента:

"states" : [
    50,
    120
]

Он сводит ответы фрагментов до одной итоговой прибыли (суммируя значения) и возвращает это значение как результат агрегирования, чтобы получить ответ:

{
  ...

  "aggregations": {
    "profit": {
      "value": 170
    }
  }
}

Другие параметры

params

Необязательный. Объект, содержимое которого будет передано как переменные в init_script, map_script и combine_script. Это может быть полезно для управления поведением агрегирования и для хранения состояния между скриптами. Если этот параметр не указан, по умолчанию будет эквивалент следующего:

"params" : {}

Пустые корзины

Если родительская корзина агрегирования метрик на основе скриптов не собирает никаких документов, из фрагмента возвращается пустой ответ агрегирования с значением null. В этом случае переменная reduce_script's states будет содержать null в качестве ответа от этого фрагмента. reduce_script должны ожидать и обрабатывать ответы null от фрагментов.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-aggregations-metrics-scripted-metric-aggregation.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API