Elasticsearch - поисковая система
Устанока
Установка и настройка Elasticsearch
- Установите максимальный размер открытых дескрипторов файла для пользователя от 32k до 64k
nano /etc/sysctl.conf
vm.max_map_count = 262144
- Если возможно, отключите свопинг памяти для процессов Elasticsearch. Обратите внимание, что в виртуальных средах это может привести к неожиданным результатам.
- Установите значение -Xms равным -Xmx (то же самое что установить значение переменной среды ES_HEAP_SIZE).
- Оставьте некоторое количество памяти, чтобы кеш операционной системы мог использовать его для Lucene.
Установка плагинов
elasticsearch-HQ
$ plugin -install royrusso/elasticsearch-HQ
elasticsearch-head
$ plugin -install mobz/elasticsearch-head
Клиент для выполнения базовых операций https://mobz.github.io/elasticsearch-head/
elasticsearch-gui
$ plugin install jettro/elasticsearch-gui
elasticsearch-analysis-icu - ICU Analysis for Elasticsearch 17
$ plugin install elasticsearch/elasticsearch-analysis-icu/2.7.0
elasticsearch-analysis-morphology - Morphological Analysis Plugin for ElasticSearch
Пример использования в запросе: Morphological Analysis Plugin for ElasticSearch - Пример использования
ElasticSearch 17
$ plugin -install analysis-morphology -url http://dl.bintray.com/content/imotov/elasticsearch-plugins/org/elasticsearch/elasticsearch-analysis-morphology/1.2.1/elasticsearch-analysis-morphology-1.2.1.zip
ElasticSearch 2.3.1
$ plugin install http://dl.bintray.com/content/imotov/elasticsearch-plugins/org/elasticsearch/elasticsearch-analysis-morphology/2.3.1/elasticsearch-analysis-morphology-2.3.1.zip
elasticsearch-mapper-attachments - Mapper Attachments Type for Elasticsearch
$ plugin install elasticsearch/elasticsearch-mapper-attachments/3.1.2
Проверка работоспособности сервера
$ curl -XGET http://localhost:9200/_stats/?pretty $ curl -XGET http://localhost:9200/_nodes/?pretty $ curl --silent-XGET"http://localhost:9200/_snapshot/_all"
$ curl --silent-XGET"http://localhost:9200/_cat/nodes?pretty" mbp-mirocow 192.168.1.147 11786.88 d * Mirocow
Создание дампа / Dump create
nano /usr/local/etc/elasticsearch/elasticsearch.yml
path.repo: ["/usr/local/var/elasticsearch/snapshot"]
Регистрация
curl -XPUT'http://localhost:9200/_snapshot/backup'-d'{ "type": "fs", "settings": { "location": "/usr/local/var/elasticsearch/snapshot", "compress": true } }'
- где:
- backup - название репозитория
- /usr/local/var/elasticsearch/snapshot - папка с содержанием самого репозитория
Проверка регистрации
curl -XGET"http://localhost:9200/_snapshot/_all?pretty"
ответ от elasticsearch
{ "backup" : { "type" : "fs", "settings" : { "compress" : "true", "location" : "/usr/local/var/elasticsearch/snapshot/backup" } } }
Проверка целостности
curl -XPOST"http://localhost:9200/_snapshot/backup/_verify
ответ от elasticsearch
{"nodes":{"zKsDO_G3SlCdbLlhVmgLKA":{"name":"Vapor"}}}
Создание snapshot / Backup
curl -XPUT"http://localhost:9200/_snapshot/backup/my_index/?wait_for_completion=true"
Где my_index является существующим индексом.
Проверить наличие инднеса можно командой
curl --silent-XGET"http://localhost:9200/_stats?pretty"|grep my_index
Удаление регистрации репозитория
curl -XDELETE'http://localhost:9200/_snapshot/backup'
Восстановление / Restore
Настройка
Если ранее небыл зарегистрирован.
curl -XPUT 'http://localhost:9200/_snapshot/_restore?wait_for_completion=true' -d '{ "type": "fs", "settings": { "location": "/usr/local/var/elasticsearch/snapshot", "compress": true } }'
- где:
- backup - название репозитория
- /usr/local/var/elasticsearch/snapshot - папка с содержанием самого репозитория
Проверка
curl -XPOST http://localhost:9200/_snapshot/backup/_verify?pretty
Восстановление
curl -XPOST http://localhost:9200/_snapshot/backup/_restore?pretty
Запрос поиска
Способы запроса
GET
Вывод всех документов из индекса
curl -XGET'localhost:9200/test/_search?q=*&pretty'
REST
Вывод всех документов из индекса
curl -XPOST'localhost:9200/1vse/_search?pretty'-d' { "query": { "match_all": {} } }'
Доступные параметры для REST запросов
curl -XPOST'localhost:9200/1vse/_search?pretty'-d' { "query": { "match_all": {} }, "size": 1 }'
curl -XPOST'localhost:9200/1vse/_search?pretty'-d' { "query": { "match": { "title": "Thomson T50E10DHU-01B" } }, "_source": ["title", "category", "brand"] }' curl -XPOST'localhost:9200/1vse/_search?pretty'-d' { "query": { "match_phrase": { "category": "телевизоры" } }, "_source": ["title", "category", "brand"] }' curl -XPOST'localhost:9200/bank/_search?pretty'-d' { "query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ] } } }'
- query - {}
- match_all
- match_phrase - Совпадение фразы
- match_phrase_prefix
- match
- bool - {}
- must - []
- match - {}
- should
- match - {}
- must_not
- match - {}
- from - Параметр from задаёт с какого документа в индексе нужно начинать.
- size - Параметр size как много документов будет возвращено.
- sort - { "balance": { "order": "desc" } }
- _source - Параметр получает массив полей, которые необходимо вернуть. ["account_number", "balance"]
Поиск по регулярным выражениям
curl -XGET'http://localhost:9200/_search'-d'{ "filter": { "bool": { "should": [ { "regexp": { "word": "мульт.*" } }, { "regexp": { "word": "фильм.*" } } ], "must_not": { "terms": { "word": ["видео", "скачать"] } } } } }'
Примеры запросов / Query DSL
curl -XGET http://localhost:9200/1vse/product/_search/-d'{ "size": 10, "query": { "bool": { "should": [ { "function_score": { "weight": 100, "query": { "match": { "product.title": "samsung" } } } }, { "function_score": { "weight": 80, "query": { "match_phrase_prefix": { "product.title": "samsung" } } } } ] } } }'
- где:
- 1vse - название БД
- product.title - название таблицы
Ошибки / Errors
- snapshot_missing_exception:
{"type": "no_such_file_exception","reason/usr/local/var/elasticsearch/snapshot/snap-snapshot.dat"}
- SnapshotMissingException:
{"error":"SnapshotMissingException[[backup:snapshot] is missing]; nested: FileNotFoundException[/usr/local/var/elasticsearch/snapshot/snapshot-snapshot (No such file or directory)]; ","status":404}
snapshot не найден, так как дамп создавался с отличным названием снапшота от snapshot
Создание индексов
Данная операция создаст инжекс test
$ curl -XPUT"http://localhost:9200/test?pretty"{"acknowledged" : true}
Получить список созданых индексов
$ curl --silent-XGET"http://localhost:9200/_cat/indices?pretty" yellow open 1vse 511477850 197.3mb 197.3mb yellow open 1vse_logs 514399140 1.6gb 1.6gb
$ curl --silent-XGET"http://localhost:9200/_cat/indices?v" health status index pri rep docs.count docs.deleted store.size pri.store.size yellow open 1vse 511477850 197.3mb 197.3mb yellow open 1vse_logs 514399140 1.6gb 1.6gb
Фильтры
Фильтр worddelimiter
Фильтр worddelimiter разбивает слова на несколько частей. Небольшой пример: представьте, что вы допустили опечатку в предложении “To be or not to be.That is the question”. Если вы обратите внимание, то заметите отсутствие пробела после точки. Без этого фильтра Elasticsearch проиндексирует “be.That” как одно слово - “bethat”. При помощи этого фильтра мы указываем ему индексировать эти слова по отдельности - “be” и “that”.
Примеры:
Фильтр stopwords
Фильтр stopwords состоит из списка слов запрещенных к индексированию. Например он исключает такие слова, как “and”, “a”, “the”, “to” и т.д. Конечно этот список уникален для каждого языка, но существует довольно много заготовок, которые вы можете использовать.
Примеры:
Фильтр snowball
Фильтр snowball используется для группировки слов по их основе. Фильтр применяет набор правил для правильного определения основы слова. Это означает, что разные настройки могут выдавать разные результаты. Например слова “indexing”, “indexable”, “indexes”, “indexation” и т.д. получать основу “index”. Хотелось бы отметить, что вы получите результат “Make my string indexable”, запросив “Indexing string”.
Примеры:
Фильтр elison
Фильтр elison имеет большее значения для некоторых языков (например французский) и не так важен для других (например английский). Он исключает маловажные слова перед индексированием, например “j’attends que tu m’appelles” (Я жду вашего звонка) проиндексируется как “attends que tu appelles” (наконце слова “que” и “tu” будут исключены фильтром stopwords). Как вы видите слова “j’” и “m’” (Я) были удалены из-за настройки фильтра elison.
Примеры:
Фильтр lowercase
Фильтр asciifolding
Заменяет все Unicode символы, не входящие в латинский алфавит на их ascii эквивалент.
Лексеры
nGram
Роль лексера nGram очень высока. Например, наш поиск “funny pony” был разбит на несколько частей. Вот два примера:
Пример 1
"min_gram" : "2", "max_gram" : "3"
Результат: fu, fun, un, unn, nn, nny, po, pon, on, ony, ny 2-ой пример с лучшей настройкой:
Пример 2
"min_gram" : "3", "max_gram" : "20" Результат: fun, funn, funny, unn, unny, nny, pon, pony, ony
Анализаторы
По умолчанию в Eldsticseach включен регистрозависимый анализатор поиска. Для его отключения используем ниже следующие настройки в конфигурационом файле elasticsearch.yml
settings: index: analysis: analyzer: string_lowercase: tokenizer: keyword filter: lowercase
Мапинг
$ curl -XGET"http://localhost:9200/1vse_logs/_mapping?pretty=true"
Примеры индексов
settings: index: analysis: analyzer: app_analyzer: type: custom tokenizer: nGram filter : [stopwords, app_ngram, asciifolding, lowercase, snowball, worddelimiter] app_search_analyzer: type: custom tokenizer: standard filter : [stopwords, app_ngram, asciifolding, lowercase, snowball, worddelimiter] tokenizer: nGram: type: "nGram" min_gram: 2 max_gram: 20 filter: snowball: type: snowball language: English app_ngram: type: "nGram" min_gram: 2 max_gram: 20 worddelimiter : type: word_delimiter stopwords: type: stop stopwords: [_french_] ignore_case : true
Работа с документом
Подокументно
Заполенение индекса
$ curl -XPUT"http://localhost:9200/test/external/1?pretty"-d' { "name": "test" }'{"_index" : "test", "_type" : "external", "_id" : "1", "_version" : 1, "created" : true}
Обновление документа
$ curl -XPOST"http://localhost:9200/test/external/1?pretty"-d' { "name": "test" }'{"_index" : "test", "_type" : "external", "_id" : "1", "_version" : 1, "created" : true}
Получение документа из индекса по ID
$ curl -XGET"http://localhost:9200/test/external/1?pretty"{"_index" : "test", "_type" : "external", "_id" : "1", "_version" : 3, "found" : true, "_source": {"name": "test"}}
Удаление документа из индекса
Удаление по индексу
curl -XDELETE'localhost:9200/customer/external/2?pretty'
Мы также имеем возможность удалить несколько документов совпавших с условием запроса. Данный пример показывает как удалить все документы из индекса customers, содержащие «John»:
curl -XDELETE'localhost:9200/customer/external/_query?pretty'-d' { "query": { "match": { "name": "John" } } }'
Работа с частичными данными документа
Настройки elasticsearch.yml
script.update: on script.mapping: on script.engine.groovy.file.aggs: on script.engine.groovy.file.mapping: on script.engine.groovy.file.search: on script.engine.groovy.file.update: on script.engine.groovy.file.plugin: on script.engine.groovy.indexed.aggs: on script.engine.groovy.indexed.mapping: on script.engine.groovy.indexed.search: on script.engine.groovy.indexed.update: on script.engine.groovy.indexed.plugin: on script.engine.groovy.inline.aggs: on script.engine.groovy.inline.mapping: on script.engine.groovy.inline.search: on script.engine.groovy.inline.update: on script.engine.groovy.inline.plugin: on
Создание массива
$ curl -s-XPOST'localhost:9200/1vse/product_for_mapping/1/_update'-d'{ "script" : "if(ctx._source.aliases.size() == 0){ctx._source.aliases = [];}" }'
Добавление в массив
$ curl -XPOST'localhost:9200/1vse/product_for_mapping/1/_update'-d'{ "script" : "ctx._source.aliases += alias", "params" : { "alias" : "Manfrotto MV-M500A" } }'
Удаление из массива
$ curl -s-XPOST'localhost:9200/1vse/product_for_mapping/1/_update'-d'{ "script" : "for (int i = 0; i < ctx._source.aliases.size(); i++){if(ctx._source.aliases[i] == value){ctx._source.aliases.remove(i);}}", "params" : { "value" : "Manfrotto MVM500A XXX" } }'
Пакетная обработка документов
curl -XPOST'localhost:9200/customer/external/_bulk?pretty'-d' {"index":{"_id":"1"}} {"name": "John Doe" } {"index":{"_id":"2"}} {"name": "Jane Doe" }
Данный пример обновляет первый документ (с ID равным 1) и затем удаляет второй документ (с ID равным 2) в одной массовой операции:
curl -XPOST'localhost:9200/customer/external/_bulk?pretty'-d' {"update":{"_id":"1"}} {"doc": { "name": "John Doe becomes Jane Doe" } } {"delete":{"_id":"2"}}'
Параметры выдачи
- _source -
- _score - Оценка - это числовое значение, которое является относительной мерой того, насколько документ совпадает с поисковым запросом, который мы создали. Большие значения оценки показывают более релевантные (более полно совпадающие) документы, меньшие значение - менее релевантные.
Агрегация
Клиенты
- Elastica - PHP клиент
- https://github.com/taskrabbit/elasticsearch-dump - Дампер на nodejs
- https://github.com/jprante/elasticsearch-jdbc - JDBC importer for Elasticsearch
Yii2
Дискусии/Форумы
- https://discuss.elastic.co/c/in-your-native-tongue/15-category (текущая группа)
- https://groups.google.com/forum/#!forum/elasticsearch-ru (бывшая группа)
Документация/Статьи
Видео
- https://www.youtube.com/watch?v=otc_tRYnjmoБезопастность или способы взлома Elasticsearch из фронтенда (RUS)
- https://vimeo.com/111068769 - Elasticsearch, Logstash, Kibana
- https://www.youtube.com/watch?v=IsOkcielysE - Elasticsearch, Logstash