Анализатор текста

Когда вы индексируете строки, они анализируются по умолчанию. Каждая строка, отображаемая как текст, проходит через анализатор, который может внести различные изменения. В elasticsearch такой анализатор по умолчанию называется стандартным анализатором. Стандартный анализатор может применяется к английскому (и большинству латинских языков), разбивает строку на токены (слова), а также переводит все токены в нижний регистр. Анализатор по умолчанию также удаляет знаки препинания. Поэтому если вы ищите строки с заглавными буквами или без количество найденных данных буде одинаковым.

Например, вы ищите текст Мой текст, тектс2. Анализатор разобьёт эту строку на 3 токена (слова): мой, текст, текст2. Затем произведёт 3 отдельных запроса для каждого из токенов, результаты которых будут объединены.

Естественно если есть стандартный анализатор, то есть конечно и другие. Есть много других анализаторов, в том числе пробелов (whitespace), остановок (stop), шаблонов (patterns) и многие другие. Список всех анализаторов можно получить тут.

Синтаксис изменения стандартного анализатора:

#для поля title
PUT myindex
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}   

PUT myindex/_mapping
{
  "properties": {
    "title": {
      "type": "text",
      "analyzer": "whitespace"
    }
  }
}

Для проверки в консоли:

POST _analyze
{
  "analyzer": "standard",
  "text": "Мой текст, тектс2"
}

Анализатор ключевых слов (Keyword Analyzer)

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

Допустим у нас есть тект Южная Африка и стандартный анализатор разобьёт его на южная, африка. Для такой ситуации отлично подойдёт анализатор ключевых слов (Keyword Analyzer). Он в отличии о стандартного не разобьёт на токены (слова), но и не переведёт всё в нижний регистр.

Для проверки в консоли:

POST _analyze
{
  "analyzer": "standard",
  "text": "Южная Африка"
}
POST _analyze
{
  "analyzer": "keyword",
  "text": "Южная Африка"
}

Разница между text и keyword

Для реализации поиска без разбития на токены (слова) можно использовать и стандартный анализатор, но с одним отличием к полю добавляется .keyword, например field1.keyword. Суть в том, что Elasticsearch динамически отображает все строки в 2 типах данных: text и keyword. По умолчанию, когда вы ищите поле, стоит тип text. Keyword чувствителен к регистру, и поиск должен включать все слова (у text можно искать по одному слову).

Для примера создадим новый документ и проверим его структуру.

PUT my_index/_doc/1
{
  "field1" : "Южная Африка"
}

GET my_index/_mapping

В результате получим:

{  "my_index" : {
    "mappings" : {
      "properties" : {
        "field1" : {
    ----->"type" : "text",
          "fields" : {
      ----->"keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }          }        }      }    }  }}

Установка типа

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

Пример установки типов для множества полей;

PUT myindex
{
  "mappings": {
    "properties": {
      "filed1": {
        "type": "text",
        "analyzer": "whitespace"
      },
      "filed2": {
        "type": "keyword",
        "analyzer": "whitespace"
      },
      "filed3": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
        }
      }
    }
  }
}   

В итоге

  • Elasticsearch имеет два типа строковых данных: text и keyword.
  • Вы можете выставить тип сами
  • Text предназначен для полнотекстового поиска
  • Keyword предназначен для точного поиска, агрегирования и сортировки
  • По умолчанию каждая строка динамически отображается дважды: как text и как keyword