Elasticsearch

Elasticsearch Введение — 1.1 Основные понятия

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

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

Основные понятия Elasticsearch

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

В этом разделе мы рассмотрим основные понятий и терминологию Elasticsearch. Начнем с основных моментов, вставка, обновление и поиск. Если вы знакомы с SQL, в таблицы ниже показаны эквивалентные термины в Elasticsearch.

SQL Elasticsearch
База данных Индекс
Таблица Тип
Ряд Документа
Колонка Поле

 Документ

В Elasticsearch данные хранятся в виде документов JSON (Javascript Object Notation). Большинство хранилищ данных NoSQL используют JSON для хранения своих данных, поскольку формат JSON очень лаконичный, гибкий и понятный людям. Документ в Elasticsearch очень похож на строку по сравнению с реляционной базой данных. Допустим, у нас есть таблица User со следующей информацией.

id name age gender email
1 Иван 14 m ivan@gmail.com
2 Lena 20 f lena@gmail.com

Кроме того Elasticsearch поддерживает хранение вложенных объектов:

Elascticsearch построен для обработки неструктурированных данных и может автоматически определять типы данных полей документа. Вы можете индексировать новые документы или добавлять новые поля без изменения схемы. Этот процесс также известен как динамическое отображение. Подробности обсудим на 3 уроке.

Индекс

Индекс похож на базу данных. Термин индекс не следует путать с индексом базы данных, как можно предложить если вы знакомы с реляционными базами данных. Индекс подразумевает логическую группировку Типов (таблиц). Имя индекса должно быть уникальным и состоять из строчных букв.

Тип

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

Например тип для статей:

Тип для комментариев:

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

Кластер и узел

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

На рисунке выше кластер имеет три узла с именами elasticsearch1, elasticsearch2, elasticsearch3. Эти три узла работают вместе, чтобы обрабатывать все запросы индексирования и извлечения данных. В зависимости от потребностей вашего приложения вы можете добавлять и удалять узлы (серверы) «на лету». Да и такая замечательная возможность есть в Elasticsearch мы обсудим это в следующих уроках.

Shard (осколок или шард)

Индекс представляет собой набор из одного или нескольких шардов. За счет чего Elasticsearch может хранить информацию объем которой превышает возможности одного сервера. Elasticsearch использует Apach Lucene для индексирования и обработки запросов. Шард — это не что иное, как экземпляр Apache Lucene.  В следующих уроках мы обсудим почему именно Apache Lucene и как он используется в Elasticsearch.

Elasticsearch Введение — 1.2 Взаимодействие

Взаимодействие с Elasticsearch

Основной способ взаимодействия с Elasticsearch — REST API. По умолчанию API — интерфейс Elasticsearch работает на порту 9200. Api можно классифицировать на следующие виды:

  • API документов: CRUD (Create Retrieve Update Delete) операции с документами
  • API поиска: поиск чего бы то ни было
  • API Индексов: управление индексами (создание, удаление …)
  • API Cat: вместо JSON данных возвращаются в табличном виде
  • API кластера: для управления кластером

Для каждого вида в дальнейшем будет отдельный урок. А сейчас мы рассмотрим некоторые основные CRUD операции API документов. Этот раздел представляет собой просто краткое введение о том, как управлять данными с помощью API документов. Кроме того стоит заметить, что есть клиентские библиотеки для большинства популярных языков программирования. По сути они являются оберткой вокруг REST API.

Для примера представим, что мы создаем интернет магазин. И хотим использовать Elasticsearch в качестве поиска. Мы будем использовать индекс с именем example1 и хранить все продукты  в типе product. Каждый продукт, который мы хотим индексировать, представляет собой JSON документ. И начнем с создания нового документа о продукте, затем запросим информацию о нем по его идентификатору, потом обновим данные в нем и в завершении удалим.

Создание документа

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

Elasticsearch автоматически создаст индекс example1 и тип product если они еще не существуют.

В ответ на запрос выше мы получим следующее:

В ответе мы увидим, что Elasticsearch создал документ с версией 1 + доп информация о том куда добавился документ. Поскольку мы создали документа с использованием HTTP метода PUT нам необходимо было задать id документа иначе мы получим ошибку.

Если у вас нет уникального идентификатора, вы можете использовать HTTP POST тогда Elasticsearc создаст уникальный id за вас. Например:

Ответ:

Собственно вот и созданный id AV1hL8Dq3Zz-g306rrqI. Если попробовать сделать запрос PUT и передать уже существующий id, произойдет замена документа и увеличение параметра _version:

Как вы заметили created = false, а _version = 2.

Получение существующего документа

Чтобы получить документ нам надо знать индекс, тип и уникальный идентификатор документа. Попробуем получить недавно созданный документа с помощью следующего запроса:

Как видите результат содержит не только сам документ который храниться в полу _source, но и дополнительная информация, например что документ был найден found = true, текущая версия _version = 2 напомню, что она увеличивается каждый раз при изменении документа.

Обновление существующего документа

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

Существуют разные способы обновление документа, подробно мы разберем эту тему на других уроках. А пока рассмотрим основы.

Частичное обновление документа

Давайте обновим категорию у недавно созданного документа:

«result»: «updated» значит все прошло успешно, заметьте _version тоже увеличилось. Доступны более сложные сценарии обновления, но как я уже говорил рассмотрим их позже.

 Удаление существующего документа

Для удаления существующего документа нам необходимо использовать HTTP метод DELETE передав в него путь, как для получения документа.

Ответ:

result = deleted, значит операция прошла успешно и документ был удален.