From 84f03d62256639d5b81fd4991e6854a723ca8dbd Mon Sep 17 00:00:00 2001 From: Konstantin Sirotkin Date: Thu, 16 Jul 2020 12:28:57 +0300 Subject: [PATCH] improved docs --- docs/guide-ru/README.md | 27 +++++---- docs/guide-ru/installation.md | 58 ++++++++++++------ docs/guide-ru/mapping-indexing.md | 99 ++++++++++++++++++++++--------- docs/guide/README.md | 12 ++-- docs/guide/installation.md | 27 +++++---- docs/guide/mapping-indexing.md | 27 +++++++-- 6 files changed, 168 insertions(+), 82 deletions(-) diff --git a/docs/guide-ru/README.md b/docs/guide-ru/README.md index 92d351042..f3d718d11 100644 --- a/docs/guide-ru/README.md +++ b/docs/guide-ru/README.md @@ -1,22 +1,23 @@ -Расширение Elasticsearch для Yii 2 -================================= +# Расширение Elasticsearch для Yii 2 Расширение обеспечивает интеграцию [Elasticsearch](https://www.elastic.co/products/elasticsearch) в фреймворк Yii2. -Включает в себя базовую поддержку запросов/поиска, а также реализует шаблон `ActiveRecord`, который позволяет сохранять активные записи в Elasticsearch. +Включает в себя базовую поддержку запросов/поиска, а также реализует шаблон `ActiveRecord`, который позволяет сохранять +активные записи в Elasticsearch. + + +## Как начать -Как начать ----------- * [Установка](installation.md) -Использование -------------- -* [Сопоставление данных и индексация](mapping-indexing.md) + +## Использование + +* [Структура данных и индексы](mapping-indexing.md) * [Использование Query](usage-query.md) -* [Использование ActiveRecord](usage-ar.md) +* [Использование ActiveRecord/ActiveQuery](usage-ar.md) * [Работа с провайдерами данных](usage-data-providers.md) -Дополнительно -------------- + +## Дополнительно + * [Использование Elasticsearch DebugPanel](topics-debug.md) -* Определение отношений с записями, чьи первичные ключи не являются частью атрибутов -* Получение записей из разных индексов/типов diff --git a/docs/guide-ru/installation.md b/docs/guide-ru/installation.md index 0a7990e36..30419d754 100644 --- a/docs/guide-ru/installation.md +++ b/docs/guide-ru/installation.md @@ -3,28 +3,33 @@ ## Требования -Требуется версия Elasticsearch 1.0 или выше. +Расширение поддерживает версии Elasticsearch 5.0 и выше. Совместимость с последними версиями веток Elasticsearch 5.x, +6.x и 7.x тестируется автоматически. -## Получение с помощью Composer -Предпочтительный способ установки расширения через [composer](http://getcomposer.org/download/). +## Настройка Elasticsearch -Для этого запустите -``` -php composer.phar require --prefer-dist yiisoft/yii2-elasticsearch -``` +Для реализации отдельных функций, таких как [[yii\elasticsearch\ActiveRecord::updateAllCounters()|updateAllCounters()]], +в расширении используются инлайн-скрипты. Скрипты написаны на языке `painless`, который Elasticsearch обычно выполняет +в песочнице. В современных версиях сервера запуск таких скриптов разрешен по умолчанию, поэтому специально ничего +настраивать не нужно. Тем не менее, для более старых серверов, например, версии 5.0, запуск инлайн-скриптов нужно явно +разрешить. В [документации Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-security.html) +это описано более подробно. + + +## Установка через Composer -или добавьте +Предпочтительный способ установки расширения - с помощью [composer](http://getcomposer.org/download/). -```json -"yiisoft/yii2-elasticsearch": "~2.0.0" +``` +composer require --prefer-dist yiisoft/yii2-elasticsearch ``` -в секцию **require** вашего composer.json. ## Настройка приложения -Для использования расширения, просто добавьте этот код в конфигурацию вашего приложения: +Для работы с расширением нужно добавить класс [[yii\elasticsearch\Connection|Connection]] к компонентам приложения и +настроить его: ```php return [ @@ -36,14 +41,31 @@ return [ ['http_address' => '127.0.0.1:9200'], //настройте несколько хостов, если у вас есть кластер ], + // установите autodetectCluster = false, чтобы не определять адреса узлов в кластере автоматически + // 'autodetectCluster' => false, + 'dslVersion' => 7, // по умолчанию - 5 ], - ] + ], ]; ``` -Соединение поддерживает автоматическое обнаружение кластера Elasticsearch, который включен по умолчанию. -Вам не нужно указывать все узлы кластера вручную, Yii будет обнаруживать другие узлы кластера и подключаться к случайно выбранному узлу по умолчанию. Вы можете отключить эту функцию, установив [[yii\elasticsearch\Connection::$autodetectCluster]] в `false`. +В параметрах соединения нужно задать хотя бы один узел. По умолчанию выполняется автоматическое определение узлов +кластера. Расширение выполняет запрос `GET /_nodes` к первому узлу из списка и получает адреса всех узлов в кластере. +Затем из этих узлов случайным образом выбирается активный узел. + +Такое поведение можно отключить, установив параметр [[yii\elasticsearch\Connection::$autodetectCluster|$autodetectCluster]] +равным `false`. Тогда активным станет произвольный узел из тех, что заданы в конфигурации. + +> Для нормальной работы автоопределения узлов кластера, в узлах, которые возвращает запрос `GET /_nodes`, должно быть +> корректно задано поле `http_address`. Со стандартным сервером Elasticsearch обычно не возникает никаких сложностей, но +> известны случаи, когда нестандартные сборки, особенно в AWS, возвращают некорректные данные. В таком случае можно +> отключить автоопределение и задать список узлов вручную. +> +> Также автоопределение можно отключить чтобы ускорить работу расширения. Если в кластере предусмотрен отдельный +> [координирующий узел](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html#coordinating-only-node), +> можно направлять все запросы только к нему. Для кластеров, в которых всего несколько узлов с известными адресами, +> целесообразно объявить эти узлы в конфигурации явно и сэкономить время на ненужном запросе. -> **NOTE:** для корректной работы автоматического обнаружения кластера, запрос узлов `GET /_nodes` должен возвращать поле `http_address` для каждого узла. -По умолчанию они возвращаются настоящими экземплярами Elasticsearch, но, они недоступны в таких средах как AWS. -В этом случае вам необходимо отключить обнаружение кластера и указать хосты вручную. \ No newline at end of file +Также в конфигурации нужно задать версию языка, который используется для работы с сервером. Значение параметра соответствует +версии Elasticsearch. Для ветки 5.x параметр [[yii\elasticsearch\Connection::$dslVersion|$dslVersion]] должен быть равен +`5`, для ветки 6.x - `6`, для ветки 7.x - `7`. Значение по умолчанию - `5`. diff --git a/docs/guide-ru/mapping-indexing.md b/docs/guide-ru/mapping-indexing.md index 3c5d9fdb4..1540bbaf5 100644 --- a/docs/guide-ru/mapping-indexing.md +++ b/docs/guide-ru/mapping-indexing.md @@ -1,37 +1,80 @@ -Сопоставление и индексация -================== +# Структура данных и индексы -## Создание индексов и сопоставления -Так как не всегда возможно обновлять сопоставления Elasticsearch поэтапно, рекомендуется создать несколько статических методов в вашей модели, которые занимаются созданием и обновлением индекса. Вот пример того, как это можно сделать. +## Сравнение с SQL + +[В документации Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/_mapping_concepts_across_sql_and_elasticsearch.html) подробно описаны основные понятия Elasticsearch и баз данных SQL, и как они соответствуют друг другу. Рассмотрим основное. + +Кластер Elasticsearch состоит из отдельных серверов - узлов. Клиент отправляет запросы к одному из них. Узел передает +запрос остальным узлам кластера, собирает результаты и выдает ответ клиенту. Таким образом, кластер или представляющий +его узел примерно соответствуют базе данных SQL. + +Данные в Elasticsearch хранятся в индексах. Индекс соответствует таблице SQL. + +Индекс состоит из документов. Документ подобен строке в таблице SQL. В этом расширении [[yii\elasticsearch\ActiveRecord|ActiveRecord]] +представляет один документ в индексе. Операция сохранения документа в индекс называется "индексирование". + +Схема или структура документа определяется так называемым маппингом. Маппинг задает поля документа, которые +соответствуют колонкам в таблице SQL. Первичный ключ в Elasticsearch - это специальное системное поле, которое нельзя +ни удалить, ни переименовать. Другие поля настраиваются разработчиком. + + +## Задание структуры полей + +Хотя Elasticsearch и создает новые поля на лету во время индексирования документов, структуру полей желательно +объявить заранее. + +Объявленное поле, как правило, нельзя изменить. Например, если текстовое поле настроено на работу с анализатором +английского языка, переключить его на другой язык можно только переиндексировав все без исключения документы в индексе. + +Отдельные изменения структуры все же допускаются. Подробнее - [в документации](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html#updating-field-mappings). + + +## Типы документов + +Изначально Elasticsearch разрабатывался как хранилище разнородных документов. Чтобы хранить документы различной +структуры в одном индексе, было введено понятие "тип". Тем не менее, этот подход себя не зарекомендовал, а с версии +[Elasticsearch 7.x](https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html) типы +уже не поддерживаются. + +В настоящее время рекомендуется в каждом индексе объявлять только один тип. Если расширение настроено на работу с +Elasticsearch 7 и выше, свойство [[yii\elasticsearch\ActiveRecord::type()|type()]] игнорируется, а в запросах тип +неявно заменяется на `_doc`. + + +## Создание вспомогательных методов + +Мы рекомендуем объявить в моделях [[yii\elasticsearch\ActiveRecord|ActiveRecord]] несколько вспомогательных методов +для работы с индексами. Ниже показана возможная реализация таких методов. ```php -class Book extends yii\elasticsearch\ActiveRecord +class Customer extends yii\elasticsearch\ActiveRecord { - //Другие атрибуты и методы класса идут здесь + // Другие атрибуты и методы класса // ... /** - * @return array Сопоставление для этой модели + * @return array Маппинг этой модели */ public static function mapping() { return [ - static::type() => [ - 'properties' => [ - 'name' => ['type' => 'string'], - 'author_name' => ['type' => 'string'], - 'publisher_name' => ['type' => 'string'], - 'created_at' => ['type' => 'long'], - 'updated_at' => ['type' => 'long'], - 'status' => ['type' => 'long'], - ] - ], + // Типы полей: https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html#field-datatypes + 'properties' => [ + 'first_name' => ['type' => 'text'], + 'last_name' => ['type' => 'text'], + 'order_ids' => ['type' => 'keyword'], + 'email' => ['type' => 'keyword'], + 'registered_at' => ['type' => 'date'], + 'updated_at' => ['type' => 'date'], + 'status' => ['type' => 'keyword'], + 'is_active' => ['type' => 'boolean'], + ] ]; } /** - * Установка (update) для этой модели + * Создание или обновление маппинга модели */ public static function updateMapping() { @@ -41,23 +84,21 @@ class Book extends yii\elasticsearch\ActiveRecord } /** - * Создать индекс этой модели + * Создание индекса модели */ public static function createIndex() { $db = static::getDb(); $command = $db->createCommand(); $command->createIndex(static::index(), [ - 'settings' => [ /* ... */ ], - 'mappings' => static::mapping(), - //'warmers' => [ /* ... */ ], //'aliases' => [ /* ... */ ], - //'creation_date' => '...' + 'mappings' => static::mapping(), + //'settings' => [ /* ... */ ], ]); } /** - * Удалить индекс этой модели + * Удаление индекса модели */ public static function deleteIndex() { @@ -68,9 +109,9 @@ class Book extends yii\elasticsearch\ActiveRecord } ``` -Чтобы создать индекс с соответствующими сопоставлениями, вызовите `Book::createIndex()`. Если вы изменили сопоставление таким образом, чтобы оно отображало обновление (например, создало новое свойство), вызовите `Book::updateMapping()`. - -Однако, если вы изменили свойство (например, перешли от `string` к` date`), Elasticsearch не сможет обновить сопоставление. В этом случае вам нужно удалить свой индекс (путем вызова `Book::deleteIndex()`), создать его заново с обновленным сопоставлением (путем вызова `Book::createIndex()`) и затем повторно заполнить его данными. +Для создания индекса с маппингом вызывается метод `Customer::createIndex()`. Если маппинг изменился, но при этом +сервер позволит обновить его на лету (например, если добавлено новое поле), вызывается метод `Customer::updateMapping()`. -## Индексация -TBD \ No newline at end of file +Если изменение значительное (например, переход от типа `string` к `date`), сервер не сможет обновить маппинг +уже существующего индекса. В таком случае придется удалить индекс с помощью `Customer::deleteIndex()`, затем создать +индекс с новым маппингом с помощью `Customer::createIndex()`), а после этого заново наполнить индекс данными. diff --git a/docs/guide/README.md b/docs/guide/README.md index 7f45c064c..9d1e8f6cd 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -1,19 +1,16 @@ -Elasticsearch Extension for Yii 2 -================================= +# Elasticsearch Extension for Yii 2 This extension provides the [Elasticsearch](https://www.elastic.co/elasticsearch/) integration for the Yii2 framework. It includes basic querying/search support and also implements the `ActiveRecord` pattern that allows you to store active records in Elasticsearch. -Getting Started ---------------- +## Getting Started * [Installation](installation.md) -Usage ------------------ +## Usage * [Data Mapping & Indexing](mapping-indexing.md) * [Using the Query](usage-query.md) @@ -21,7 +18,6 @@ Usage * [Working with data providers](usage-data-providers.md) -Additional topics ------------------ +## Additional topics * [Using the Elasticsearch DebugPanel](topics-debug.md) diff --git a/docs/guide/installation.md b/docs/guide/installation.md index b65ed64cd..ec7d1a163 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -28,7 +28,7 @@ composer require --prefer-dist yiisoft/yii2-elasticsearch ## Configuring application -To use this extension, you have to configure the Connection class in your application configuration: +To use this extension, you need to configure the [[yii\elasticsearch\Connection|Connection]] class in your application configuration: ```php return [ @@ -41,7 +41,6 @@ return [ // configure more hosts if you have a cluster ], // set autodetectCluster to false if you don't want to auto detect nodes - // (for example: you're using SLA after a special domain) // 'autodetectCluster' => false, 'dslVersion' => 7, // default is 5 ], @@ -49,16 +48,24 @@ return [ ]; ``` -The connection supports auto detection of the Elasticsearch cluster, which is enabled by default. -You do not need to specify all cluster nodes manually, Yii will detect other cluster nodes and connect to -a randomly selected node by default. You can disable this feature by setting -[[yii\elasticsearch\Connection::$autodetectCluster|$autodetectCluster]] to `false`. +The connection needs to be configured with at least one node. The default behavior is cluster autodetection. +The extension makes a `GET /_nodes` request to the first node in the list, and gets the addresses of all the +nodes in the cluster. An active node is then randomly selected from the updated node list. -Note that for cluster autodetection to work properly, the `GET /_nodes` request to the nodes specified in the -configuration must return the `http_address` field for each node. This is returned by vanilla Elasticsearch instances -by default, but has been reported to not be available in environments like AWS. In that case you need to disable -cluster detection and specify hosts manually. +This behavior can be disabled by setting [[yii\elasticsearch\Connection::$autodetectCluster|$autodetectCluster]] +to `false`. In that case an active node will be randomly selected from the nodes given in the configuration. + +> For cluster autodetection to work properly, the `GET /_nodes` request to the nodes specified in the +> configuration must return the `http_address` field for each node. This is returned by vanilla Elasticsearch instances +> by default, but has been reported to not be available in environments like AWS. In that case you need to disable +> cluster detection and specify hosts manually. +> +> It may also be useful to disable cluster autodetection for performance reasons. If a cluster has a single +> dedicated [coordinating-only node](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html#coordinating-only-node), +> it makes sense to direct all requests to that node. Is a cluster contains only a few nodes and their addresses +> are known, it may be useful to specify them explicitly. You should set the version of the domain-specific language the extension will use to communicate with the server. +The value corresponds to the version of the Elasticsearch server. For 5.x branch set [[yii\elasticsearch\Connection::$dslVersion|$dslVersion]] to `5`, for 6.x branch to `6`, for 7.x branch to `7`. Default is `5`. diff --git a/docs/guide/mapping-indexing.md b/docs/guide/mapping-indexing.md index 662a549dc..37e8565c3 100644 --- a/docs/guide/mapping-indexing.md +++ b/docs/guide/mapping-indexing.md @@ -2,13 +2,32 @@ Mapping & Indexing ================== -## Creating indices and mappings +## Comparison with SQL -Elasticsearch is a document store, and the schema of those documents is called a mapping. Every index should have a -mapping. Even though new fields will be created on the fly when documents are indexed, it is considered good practice +[Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/_mapping_concepts_across_sql_and_elasticsearch.html) provides an extensive list of concepts in Elasticsearch and SQL and how they map to one another. We'll focus on the +basics. + +An Elasticsearch cluster consists of one or more Elasticsearch instances. Requests are sent to one of the instances, +which propagates the query to other instances in the cluster, collects results, and then returns them to the client. +Therefore a cluster or an instance that represents it roughly correspond to a SQL database. + +In Elasticsearch data is stored in indices. An index corresponds to a SQL table. + +An index contains documents. Documents correspond to rows in a SQL table. In this extension, an +[[yii\elasticsearch\ActiveRecord|ActiveRecord]] represents a document in an index. The operation of saving a document +into an index is called indexing. + +The schema or structure of a document is defined in the so-called mapping. A mapping defines document fields, which +correspond to columns in SQL. In Elasticsearch the primary key field is special, because it always exists and its +name and structure can not be changed. Other fields are fully configurable. + + +## Mapping fields beforehand + +Even though new fields will be created on the fly when documents are indexed, it is considered good practice to define a mapping before indexing documents. -Generally, once an attribute is defined, it is not possible to change its type (for example, go from integer to string). +Generally, once an attribute is defined, it is not possible to change its type. For example if a text field is configured to use the English language analyzer, it is not possible to switch to a different language without reindexing every document in the index. Certain limited modifications to mapping can be applied on the fly. See [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html#updating-field-mappings) for more info.