Агрегации в Elasticsearch

Агрегирование суммирует ваши данные в виде показателей, статистики или другой аналитики. Агрегации помогут вам ответить на такие вопросы, как:

  • Каково среднее время загрузки моего веб-сайта?
  • Кто мои самые ценные клиенты с учетом объема транзакций?
  • Что будет считаться большим файлом в моей сети?
  • Сколько товаров находится в каждой товарной категории?

Elasticsearch разбивает агрегаты на три категории:

  • Агрегаты показателей, которые вычисляют показатели, такие как сумма или среднее значение, на основе значений полей.
  • Агрегаты сегментов, которые группируют документы в сегменты (buckets), также называемые ячейками (bins), на основе значений полей, диапазонов или других критериев.
  • Конвейерные агрегаты, которые принимают входные данные из других агрегатов вместо документов или полей.

Запустить агрегацию

Вы можете запускать агрегаты как часть поиска, указав параметр aggs API поиска. Следующий поиск запускает агрегацию терминов в my-field:

GET /my-index-000001/_search
{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}

Результаты агрегирования находятся в объекте aggregations ответа:

{
  "took": 78,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [...]
  },
  "aggregations": {
    "my-agg-name": {                           
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": []
    }
  }
}

Результаты для агрегации my-agg-name.

Изменение области агрегации

Используйте параметр query, чтобы ограничить количество документов, в которых выполняется агрегирование:

GET /my-index-000001/_search
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "now-1d/d",
        "lt": "now/d"
      }
    }
  },
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}

Возврат только результатов агрегирования

По умолчанию поисковые запросы, содержащие агрегирование, возвращают как результаты поиска, так и результаты агрегирования. Чтобы возвращать только результаты агрегирования, установите size равным 0:

GET /my-index-000001/_search
{
  "size": 0,
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}

Запуск нескольких агрегатов

В одном запросе можно указать несколько агрегатов:

GET /my-index-000001/_search
{
  "aggs": {
    "my-first-agg-name": {
      "terms": {
        "field": "my-field"
      }
    },
    "my-second-agg-name": {
      "avg": {
        "field": "my-other-field"
      }
    }
  }
}

Запуск субагрегаций

Агрегирование сегментов поддерживает сегрегации сегментов или метрических единиц. Например, агрегирование терминов с субагрегацией avg вычисляет среднее значение для каждого сегмента документов. Для вложенных субагрегаций нет ограничений по уровню или глубине.

GET /my-index-000001/_search
{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      },
      "aggs": {
        "my-sub-agg-name": {
          "avg": {
            "field": "my-other-field"
          }
        }
      }
    }
  }
}

Ответ вкладывает результаты субагрегации в родительскую агрегацию:

{
  ...
  "aggregations": {
    "my-agg-name": {                           
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "foo",
          "doc_count": 5,
          "my-sub-agg-name": {                 
            "value": 75.0
          }
        }
      ]
    }
  }
}

Результаты для родительской агрегации my-agg-name.

Результаты для субагрегации my-agg-name - my-sub-agg-name.

Добавить собственные метаданные

Используйте meta объект, чтобы связать настраиваемые метаданные с агрегацией:

GET /my-index-000001/_search
{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      },
      "meta": {
        "my-metadata-field": "foo"
      }
    }
  }
}

Ответ возвращает meta объект на том же месте:

{
  ...
  "aggregations": {
    "my-agg-name": {
      "meta": {
        "my-metadata-field": "foo"
      },
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": []
    }
  }
}

Вернуть тип агрегации

По умолчанию результаты агрегирования включают имя агрегата, но не его тип. Чтобы вернуть тип агрегирования, используйте параметр запроса typed_keys.

GET /my-index-000001/_search?typed_keys
{
  "aggs": {
    "my-agg-name": {
      "histogram": {
        "field": "my-field",
        "interval": 1000
      }
    }
  }
}

Ответ возвращает тип агрегирования в качестве префикса к имени агрегирования.

Некоторые агрегаты возвращают тип агрегирования, отличный от типа в запросе. Например, агрегированные термины, значимые термины и процентили возвращают разные типы агрегатов в зависимости от типа данных агрегированного поля.

{
  ...
  "aggregations": {
    "histogram#my-agg-name": {                 
      "buckets": []
    }
  }
}

Тип агрегации, histogram, за которым следует разделитель # и имя агрегации my-agg-name.

Используйте скрипты в агрегации

Если поле не совсем соответствует необходимому агрегированию, вам следует выполнить агрегирование в поле времени выполнения:

GET /my-index-000001/_search?size=0
{
  "runtime_mappings": {
    "message.length": {
      "type": "long",
      "script": "emit(doc['message.keyword'].value.length())"
    }
  },
  "aggs": {
    "message_length": {
      "histogram": {
        "interval": 10,
        "field": "message.length"
      }
    }
  }
}

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

Кеш агрегации

Для более быстрых ответов Elasticsearch кеширует результаты часто выполняемых агрегатов в кеше запросов сегментов. Чтобы получить кешированные результаты, используйте одну и ту же строку предпочтений для каждого поиска. Если вам не нужны результаты поиска, установите размер равным 0, чтобы не заполнять кеш.

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

Ограничения для длинных значений

При выполнении агрегирования Elasticsearch использует двойные значения для хранения и представления числовых данных. В результате агрегации длинных чисел, превышающих 2^53, являются приблизительными.


Читайте также:

Комментарии

Популярные сообщения из этого блога

Язык поисковых запросов в Graylog

Хэш-таблица: разрешение коллизий

Нормальные формы, пример нормализации в базе данных