Теория, лежащая в основе Elasticsearch

Это десятая статья в серии, которая поможет вам понять различные концепции, лежащие в основе Node.js, и даст вам возможность создавать готовые к работе приложения.

Эта статья предполагает, что читатель знает Вавилон. Прочтите эту статью, если вам нужно знать, как ее настроить.

Что, черт возьми, такое Elasticsearch?

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

Обычные системы управления базами данных SQL на самом деле не предназначены для полнотекстового поиска. Поэтому одна из основных причин, по которой люди используют Elasticsearch, - это поиск текста за несколько миллисекунд.

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

1. Автозаполнение и мгновенный поиск

2. Нечеткий поиск

3. Аналитика и визуализация с помощью Kibana

4. Агрегирование данных распределенного журнала.

5. Управление производительностью приложений (APM)

В этом курсе мы не будем углубляться в Elasticsearch, так как мы сосредоточимся больше на части интеграции. Но мы рассмотрим некоторые основы Elasticsearch, чтобы понять, как его использовать.

Это также будет означать, что статья будет длинной и наполненной скучным текстом.

Ничего не могу поделать :(. Именно поэтому я решил разделить статью на две части. Одна только с теорией, а другая с фейерверком :)

Но я обещаю, что после прочтения этой статьи вы получите четкое представление об ElasticSearch.

Я рекомендую ознакомиться с руководствами Elastisearch Reference и Elastisearch Answers, чтобы получить полное представление о ES (Elasticsearch. В дальнейшем я буду называть Elasticsearch ES.).

Во-первых, давайте посмотрим, как ES хранит данные и каковы ключевые компоненты:

Кластер

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

Узел

Узел - это отдельный сервер, который является частью вашего кластера, хранит ваши данные и участвует в индексировании и поиске кластера. Узел можно настроить для присоединения к определенному кластеру по имени кластера. По умолчанию каждый узел настроен для присоединения к кластеру с именем elasticsearch.

Показатель

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

Документ

Документ - это основная единица информации, которую можно проиндексировать. Например, у вас может быть документ для одного клиента, другой документ для одного продукта и еще один для одного заказа. Этот документ представлен в формате JSON (нотация объектов JavaScript), который является широко распространенным форматом обмена данными в Интернете.

В индексе / типе вы можете хранить сколько угодно документов. Обратите внимание: ограничений нет.

Осколки и реплики

Индекс потенциально может хранить большой объем данных, который может превышать аппаратные ограничения одного узла. Например, один индекс из миллиарда документов, занимающих 1 ТБ дискового пространства, может не поместиться на диске одного узла.

Чтобы решить эту проблему, ES предоставляет возможность разделить ваш индекс на несколько частей, называемых осколками. Когда вы создаете индекс, вы можете просто определить количество сегментов, которое вам нужно. Каждый сегмент сам по себе является полностью функциональным и независимым «индексом», который может быть размещен на любом узле кластера. Шардинг важен по двум основным причинам:

  • Это позволяет вам горизонтально разделять / масштабировать объем вашего контента.
  • Он позволяет распределять и распараллеливать операции между шардами (возможно, на нескольких узлах), тем самым повышая производительность / пропускную способность.

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

Картография

Сопоставление определяет поля для документов определенного типа - тип данных (например, строковый и целочисленный) и то, как поля должны индексироваться и храниться в ES. Это похоже на схемы, определенные в реляционной базе данных.

Анализатор

Анализаторы используются во время индексирования для разбивки фраз или выражений на термины. Определенный в индексе анализатор - встроенный или настраиваемый - представляет собой просто пакет, содержащий три строительных блока нижнего уровня: символьные фильтры, токенизаторы и фильтры токенов.

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

Инвертированный индекс

Elasticsearch хранит все токены, сгенерированные анализатором, в структуре данных, известной как инвертированный индекс. Он хранит текст в структуре, которая обеспечивает очень эффективный и быстрый полнотекстовый поиск. При выполнении полнотекстового поиска мы фактически запрашиваем инвертированный индекс, а не документы JSON, которые мы определили при индексировании документов.

Возьмем пример двух документов, содержащих следующий текст:

Док №1. Я неизбежен.

Док №2: Я, я Железный человек.

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

Фактический инвертированный индекс будет хранить больше информации, такой как частота каждого термина в каждом документе, положение термина в документе и т. Д.

Отображение в деталях

Поля - это наименьшая отдельная единица данных в ES. Каждое поле имеет определенный тип и содержит один фрагмент данных, например логическое значение, строку или выражение массива. Часто бывает полезно индексировать одно и то же поле по-разному для разных целей. Например, поле string может быть проиндексировано как поле text для полнотекстового поиска и как поле keyword для сортировки или агрегирования.

Поля и типы отображения не нужно определять перед использованием. Благодаря динамическому сопоставлению новые имена полей будут добавляться автоматически при индексации документа. Новые поля могут быть добавлены как к типу отображения верхнего уровня, так и к внутреннему объекту и nested полям. Мы также можем создать настраиваемое сопоставление для нашего индекса, как показано ниже:

Мы увидим более сложное использование, когда реализуем собственный индекс.

Анатомия анализатора

Анализатор имеет три строительных блока нижнего уровня: фильтры символов, токенизаторы и фильтры токенов.

Символьные фильтры. Символьный фильтр принимает исходный текст в виде потока символов и может преобразовывать поток, добавляя, удаляя или изменяя символы. Например, символьный фильтр html_strip удаляет все теги HTML из текста.

Токенизаторы: токенизатор принимает поток символов, разбивает его на отдельные токены (обычно отдельные слова) и выводит поток токенов. Например, токенизатор whitespace разбивает текст на токены всякий раз, когда видит какие-либо пробелы. Я действительно рекомендую пройти через несколько общих токенизаторов.

Фильтры токенов: фильтр токенов получает поток токенов и может добавлять, удалять или изменять токены. Например, фильтр токенов lowercase преобразует все токены в нижний регистр, фильтр токенов stop удаляет общие слова (стоп-слова), такие как the, из потока токенов, а фильтр токенов synonym вводит синонимы в поток токенов.

Обратите внимание, что анализатор может иметь ноль или более символьных фильтров и фильтров токенов, но он должен иметь только один токенизатор.

Давайте возьмем пример настраиваемого анализатора, который мы можем построить, используя standard tokenizer, html_strip char filter и lowercase token filter. Стандартный токенизатор делит текст на термины по границам слов (а не только по пробелам). Удаляет большинство знаков препинания.

Мы можем проверить, как будет работать наш пользовательский анализатор, используя следующий API, предоставленный ES. Не волнуйтесь, вы увидите, как использовать этот API в следующей статье.

Он вернет два токена: i'm и inevitable. Давайте представим себе, как это происходит:

Теперь мы сохранили данные так, как мы хотим искать и извлекать, но как нам это сделать?

Запрос DSL

Elasticsearch предоставляет полный DSL запросов (язык, специфичный для домена) на основе JSON для определения запросов. Одним из наиболее распространенных и простых предложений запроса является match. В этой статье мы будем использовать запрос match для получения результатов. Но подробнее о Query DSL вы можете прочитать здесь.

Мы можем использовать запрос на совпадение следующим образом:

GET /my-index/_search
{
  "query":{
    "match":{
      "field_name" : "search text"
    }
  }
}

Уф!

Я думаю, что этой теории достаточно, чтобы мы запачкали руки. Так что будьте готовы к полету!

В следующей статье мы создадим наш индекс, настроим явное сопоставление, создадим настраиваемые анализаторы, загрузим документы в наш индекс и создадим API отдыха в node.js, который будет попадать в экземпляр ES с помощью Query DSL. Дальше будет много интересного. :)