По умолчанию, когда вы добавляете документ в Elasticsearch индекс создаётся автоматически если его не существует.

Например, если добавить документ в несуществующий индекс my-index-1 Elasticsearch создаст его автоматически.

PUT my-index-1/_doc/1
{
  "title": "my title is"
}

GET my-index-1/_search

Отключение автоматического создания индекса

Если вы вдруг хотите отключить поведение по умолчанию и не создавать автоматически несуществующие индексы можно использовать action.auto_create_index, выставив его значение в false.

PUT _cluster/settings
{
  "persistent": {
    "action.auto_create_index": false
  }  
}

PUT my-index-2/_doc/1
{
  "title": "my title is"
}

В итоге при попытке проиндексировать документ в несуществующий индекс вы получите ошибку {"statusCode":502,"error":"Bad Gateway","message":"Client request timeout"}.

Автоматического создания индекса по pattern

Также возможно указать какие именно индексы можно создавать автоматически всё также используя action.auto_create_index. Для этого в значение action.auto_create_index выставляется в pattern, который вас устраивает.

PUT _cluster/settings
{
  "persistent": {
    "action.auto_create_index": "my-*,metricbeat-*"
  }  
}

Разбирая пример выше получается, что автоматически будут создаваться индексы, начинающиеся на my- и metricbeat-.

Также для использования некоторых продуктов от Elastic необходимо автоматическое создание индексов для этих продуктов. Для этого рекомендуется использовать pattern с возможными значениями индексов.

PUT _cluster/settings
{
  "persistent": {
    "action.auto_create_index": "*.monitoring*,.watches,.triggered_watches,.watcher-history*,.ml*"
  }  
}

Динамическое создание полей

Если это не первая статья, которую вы читает на моём сайте то вы уже должны знать, что по умолчанию при автоматическом создании поля ему присваивается 2 типа keyword и text. Иногда бывает необходимость присваивать для определённых полей только один определённый тип, именно автоматически, а не вручную. Для этого используем dynamic_templates при создании индекса.

Например, пусть всё что строковое пусть индексируется с типом keyword.

PUT my-index-1
{
  "mappings": {
    "dynamic_templates":  [
      {
        "my_field_type": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

GET my-index-1/_mapping

{
  "my-index-1" : {
    "mappings" : {
      "dynamic_templates" : [
        {
          "my_field_type" : {
            "match_mapping_type" : "string",
            "mapping" : {
              "type" : "keyword"
            }
          }
        }
      ],
      "properties" : {
        "title" : {
          "type" : "keyword"
        }
      }
    }
  }
}

Ограничения

Иногда не лишним бывает и ограничить динамическое создание индексов либо полей. Для этого используются следующие настройки:

  • index.mapping.total_fields.limit - Максимальное количество полей в индексе (по умолчанию 1000)
  • index.mapping.depth.limit - Максимальная глубина поля, которая измеряется количеством внутренних объектов. Значение по умолчанию равно 20.
  • index.mapping.nested_fields.limit - Максимальное количество отдельных вложенных отображений в индексе. Вложенный тип следует использовать только в особых случаях, когда нужно запрашивать массивы объектов независимо друг от друга. Чтобы защитить себя от плохо спроектированных сопоставлений, этот параметр ограничивает количество уникальных вложенных типов для каждого индекса. По умолчанию 50.
  • index.mapping.nested_objects.limit - Максимальное количество вложенных объектов JSON, которое может содержать один документ для всех вложенных типов. Это ограничение помогает предотвратить ошибки нехватки памяти, когда документ содержит слишком много вложенных объектов. По умолчанию 10000.

Небольшое разъяснение по поводу index.mapping.nested_fields.limit. Например, если в следующем примере мы не определяем поле "user" как поле nested в сопоставлении, запрос для user.name: Wagner и user.car: Audi вернет совпадение, и это будет ошибкой:

{
  "group" : "staff",
  "user" : [ 
    {
      "name" : "Wagner",
      "car" :  "BMW"
    },
    {
      "name" : "Alice",
      "car" :  "Audi"
    }
  ]
}

В итоге

  • Когда вы отключаете динамические индексы не забудьте занести в белый список все шаблоны индексов для системных индексов.
  • Используя динамические шаблоны, вы можете определить отображение поля на основе его имени или типа данных.