Как определить экономичность маппинга в OpenSearch

OpenSearch logo OpenSearch

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

OpenSearch не навязывает строгую структуру документов - хранить можно любой документ. Документ можно рассматривать как эквивалент строки или записи в реляционной базе данных. Когда мы индексируем документ, создается отображение на данные. Каждое поле в маппинге может быть либо полем метаданных, либо добавленным пользовательским полем. Существуют различные типы полей маппинга, позволяющие определять различные типы полей.

Динамическое маппинг VS статический маппинг

В OpenSearch существует два различных варианта мапинга.

Динамический маппинг: При динамическом маппинге документ индексируется без определения маппинга. Новые поля добавляются на верхний уровень. Это помогает индексировать данные без определения маппинга. Следующие настройки помогут оптимизировать операции индексирования:

  • Включите определение даты и установите динамические_форматы даты.
  • По умолчанию включено определение даты, при этом сохраняются данные "created_on": "2021/01/01" будут сохраняться в формате по умолчанию ["strict_date_optional_time", "yyyy/MM/dd HH:mm:ss Z||yyy/MM/dd Z"]. При необходимости используйте пользовательский формат с помощью
  • "dynamic_date_formats": ["MM/dd/yyy"]. Отключение приведет к сохранению даты в текстовом формате.
  • Включить определение числовых значений, numeric_detection: true

По умолчанию функция numeric_detection отключена, поэтому при сохранении данных "experience_in_years": "10" будет сохранено в текстовом формате. Включение функции numeric_detection приведет к сохранению данных либо в формате float (значение равно 1.0), либо в формате long (значение равно 1).

  • Перед запуском в производство пользовательские анализаторы должны быть протестированы с помощью API анализатора. Стандартные анализаторы поддерживаются "из коробки" для естественных языков.
  • Coerce - операции индексирования будут неудачными, если индексируются грязные значения. Например, если вы пытаетесь сохранить число "10", то оно будет сохранено либо как число с плавающей точкой, либо как строка, но не как целое число. Чтобы заставить поле быть строгим, можно использовать coerce на уровне индекса или поля.
  • Можно настроить поле так, чтобы оно не индексировалось, если длина строки слишком велика и превышает необходимое количество символов. ignore_above может быть настроено в соответствии с требованиями системы. Поле можно не индексировать, если документ содержит неверные данные, используя параметр "ignore_malformed": true.

Динамический маппинг даст плохие результаты при неосознанном индексировании документа. Это поведение можно отключить как на уровне документа, так и на уровне объекта, установив для параметра dynamic значение false (игнорировать новые поля) или strict (выбрасывать исключение, если встречается неизвестное поле). По умолчанию используется значение true.

Статический маппинг: При статическом маппинге маппинг определяется до индексирования документа. Все новые поля добавляются с помощью API PUT Mappings.

Text VS Keyword

Text: Поле типа text пройдет через текстовый анализ и затем будет проиндексировано в инвертированный индекс. По умолчанию OpenSearch использует стандартный анализатор.

Например,

Текст токенизируется на 9 лексем со следующим форматом JSON для каждой лексемы, в примере ниже показана лексема:

OpenSearch позволяет создавать пользовательские анализаторы с комбинацией различных фильтров, токенизаторов и char-фильтров.

Keyword: Поле типа keyword будет индексироваться в том виде, в котором оно задано клиентом, и будет представлять собой однострочный текст в инвертированном индексе.

Пример использования:

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

Индекс на тип документа

В старых версиях OpenSearch каждый индекс мог иметь несколько типов, что приводило к неоднозначности, когда одно и то же имя встречалось в разных типах маппинга, которые внутренне поддерживались одним и тем же полем Lucene.

Индексирование документов разных типов маппинга в одном индексе, например, индексирование customer_order и customer_reviews в одном индексе приведет к избыточности, когда у нас будет несколько отзывов с одним и тем же customer_order, что приведет к разбросу данных или разрозненности документов. Поэтому рекомендуется сохранять один тип маппинга в одном индексе. Начиная с версии OpenSearch 6.0 по умолчанию индекс не позволяет сохранять несколько типов в одном индексе. Лучшим вариантом будет всегда иметь один тип документа в индексе. Единственная обязанность индекса - поддерживать один тип документа/тип маппинга в индексе.

Предотвращение взрыва маппинга - ограничение настроек

Неограниченное количество полей маппинга может привести к взрыву маппинга, что приведет к возникновению исключения Out_of_Memory. Чтобы предотвратить взрыв маппинга, необходимо обновить индексный маппинг и ограничить количество полей в документе. Рекомендуемая конфигурация полей приведена ниже.

Ограничить общее количество полей

Установите общее количество полей с помощью index.mapпинг.total_fields.limit - по умолчанию оно равно 1000.

Определить максимальную глубину полей

  • Все поля в корне, глубина=1
  • Если есть маппинг объекта на поле, глубина=2

Задайте значение index.mappпинг.depth.limit, чтобы установить желаемый предел. По умолчанию значение равно 20.

Определение максимального предела вложенных полей

Вложенные поля используются, когда необходимо проиндексировать или запросить массив или объект. Лучше всего определить количество вложенных маппингов. Вы можете установить желаемое значение index.mapping.nested_fields.limit. По умолчанию это значение равно 50.

Определение максимального предела вложенных объектов

По умолчанию один документ может иметь не более 10000 вложенных объектов по всем вложенным объектам. Для ограничения количества вложенных объектов установите значение параметра index.mapping.nested_objects.limit.

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

Увеличение времени выполнения запросов

Boost: Для улучшения релевантности мы можем повысить релевантность определенного поля. В версии Elasticsearch 5.0.0 буст времени индекса был упразднен в пользу буста времени запроса.

Заключение

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

Avatar for Gnostis
Gnostis
Добавить комментарий