Роль анализатора

Когда строки помещаются в поле типа текста (text) при индексировании, они обрабатываются анализатором (Analyzer).

Анализатор Elasticsearch можно рассматривать как конвейер, который получает исходный текст, разбивает его на токены (tokens) и возвращает их. Эти токены записываются в инвертированный индекс.

Компоненты анализатора

Каждое поле типа text обрабатываясь анализатором, проходит 3 этапа.

Character Filter (символьный фильтр) Tokenizer (Токенизатор) Token Filter (Фильтр токенизатора)
Первый компонент анализатора, работает с исходным текстом. Character Filter может принимать ноль или более фильтров. Цель символьного фильтра - преобразовать исходный текст в зависимости от используемого фильтра. Этот преобразованный текст передается следующему компоненту анализатора - Tokenizer. Tokenizer получает преобразованный текст после Character Filter и создаёт токены. У каждого анализатора (Analyzer) должен быть настроен Tokenizer. Токены, созданные Tokenizer, либо возвращаются анализатором, либо передаются Token Filter, если задана фильтрация. Последний компонент анализатора. Token Filter добавляют, удаляют или изменяют токены, созданные Tokenizer. Анализаторы (Analyzers) имеют ноль или более фильтров токенов.

Все эти три этапа поле типа text проходит поэтапно.

Использование анализатора

Для использования анализатора мы можем обратиться к его API - _analyze. Вы можете использовать большое количество типов анализатора. Весь список можно посмотреть на офсайте.

Рассмотрим использование нескольких из них:

  • Standard Analyzer - заменяет все заглавные буквы на прописные, разбивает предложение на токены используя пробел либо спецсимволы.
POST _analyze
{
  "analyzer": "standard",
  "text": "It supports lower-casing and stop words."
}

#output tokens
it, supports, lower, casing, and, stop, words
  • Language Analyzers - действует почти так же как Standard, плюс еще убирает окончания со слов. Например, вместо того, чтобы искать supports вы можете искать support. Также удаляет стоп слова (stopwords): and, or, it и т.д. Можно задавать свои собственные stopwords.
POST _analyze
{
  "analyzer": "english",
  "text": "It supports lower-casing and stop words."
}

#output tokens
support, lower, case, stop, word

Если рассматривать область применения Language analyzers то сразу модно понять что это упрощает пользователю поиск документов по ключевым словам. Логично что пользователь не будет искать слово supports, он в 95% случаев будет искать именно слово support. И благодаря использованию Language analyzers ему также будут показаны документы где находится слово supports. Тогда как без использования этого анализатора для поиска данного документа придётся искать слово supports.

Применение на index

Теперь давайте рассмотрим, как это все применить к новому индексу. Для примера будем использовать следующие критерии:

  • Имя индекса будет my-index-1
  • Применим Character Filter mapping, который позволяет заменять какое-либо значение на другое значение (My-App => MyApp)
  • Применим Tokenizer standard
  • Применим Token Filter lowercase, stop и snowball
  • Применим наш анализатор к полю title

1.Создаём сам индекс

PUT my-index-1
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": ["My-App => MyApp"]
        }
      },
      "filter": {
        "my_snowball_filter": {
          "type": "snowball",
          "language": "English"
        }
      },
      "analyzer": {
        "my_analyzer_name": {
          "type": "custom",
          "char_filter": ["my_char_filter"],
          "tokenizer": "standard",
          "filter": ["lowercase", "stop", "my_snowball_filter"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "my_analyzer_name",
        "search_analyzer": "standard"
      }
    }
  }
}

2.Проверяем на какие токены поделиться наше поле title


POST my-index-1/_analyze
{
   "text":"Introducing beta releases: Elasticsearch and My-App!",
   "analyzer": "my_analyzer_name"
}
}

#tokens
introduc, beta, releas, elasticsearch, myapp

3.Добавляем несколько документов


PUT my-index-1/_doc/3
{
   "title":"Introducing beta releases: Elasticsearch and My-App!"
}

PUT my-index-1/_doc/6
{
   "title":"Introducing beta releases: Elasticsearch and My-App!",
   "analyzer": "my_analyzer_name"
}

4.Делаем поиск по слову releas и находим документы со словом releases


GET my-index-1/_search
{
   "query":{
      "match":{
         "title": "releas"
      }
   }
}