Эта статья основана на официальных документах ElasticSearch и кратко знакомит с концепцией ElasticSearch и некоторыми простыми методами поиска.
Сначала загрузите ElasticSearch и Kibana на локальный компьютер, обратите внимание, что номера версий этих двух вещей должны быть одинаковыми, затем запустите Kibana, откройте http://localhost:5601/app/kibana, чтобы войти в интерфейс управления графическим интерфейсом, введите Dev Tools, чтобы эксплуатировать ЕС.
1. Индекс
Давайте сначала рассмотрим две концепции индексов в ES:
Процесс хранения данных в Elasticsearch называетсяпоказатель(глагол), но прежде чем индексировать документ, нужно решить, где хранить документ.
Кластер Elasticsearch может содержать несколькопоказатель(имя существительное), каждый соответствующий индекс может содержать несколькоТипы.Эти разные типы хранят несколькоДокументы* Каждый документ имеет несколькоАтрибуты.
Видно, что приведенное выше утверждение не очень гладкое, в основном потому, что индекс здесь имеет два значения:
- Существительное, указатель здесь похож на базу данных.
- глагол, индексация (глагол) документ сохраняет документ впоказатель(существительное), чтобы его можно было найти и запросить. Так же, как Insert в SQL.
пример:
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
дорожка/megacorp/employee/1
Содержит три части информации: megacorp — имя индекса (как база данных), employee (как таблица), 1 (конкретный сотрудник, как первичный ключ, идентифицирующий каждую строку). Следующий JSON — это сохраненный контент.
2. Получить документы
Получение документа похоже на запрос HTTP, выполните запрос GET для получения документа JSON:
GET /megacorp/employee/1
Подобный GET также можно изменить на HEAD, DELETE и т. д.
2.1 Облегченный поиск
Искать всех сотрудников:
GET /megacorp/employee/_search
Запросите любое указанное поле в JSON:
GET /megacorp/employee/_search?q=last_name:Smith
Поиск с использованием выражений запроса, которые поддерживают построение более сложных и надежных запросов с использованием тела запроса. :
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
2.2 Сложные запросы:
GET /megacorp/employee/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": {
"range" : {
"age" : { "gt" : 30 }
}
}
}
}
}
2.3 Полнотекстовый поиск
Полнотекстовый поиск может делать то, что традиционным реляционным базам данных трудно сделать, например, искать всех сотрудников, которые любят скалолазание:
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
Кажется, это ничем не отличается от того, что было раньше, не так ли? Но посмотрите на возвращенный результат:
"hits": [
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_score": 0.53484553,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_score": 0.26742277,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
}
]
По умолчанию Elasticsearch сортирует по показателю релевантности, то есть насколько хорошо каждый документ соответствует запросу. Первый лучший результат очевиден: Джон Смитabout
В отеле четко написано «скалолазание». Но Джейн тоже вернулся, но из-за того, что в его ключевых словах нет точного соответствия, его релевантность не так высока, как у Джона, и он отстает. Традиционные реляционные базы данных либо совпадают, либо не совпадают вовсе.
2.3 Сопоставление фраз
Так что, если я хочу сопоставлять только точные совпадения, такие как реляционная база данных? Это запрос с фразовым соответствием:match_phrase
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
вернет только те документы, которые точно соответствуют Джону.
2.4 Аналитический запрос
Перед использованием агрегации agg нужно добавить в поле запроса fileddata=true, т.к. в документации написано
Fielddata can consume a lot of heap space, especially when loading high cardinality
text
fields.
fileddata будет потреблять много места в куче, поэтому по умолчанию он отключен, и здесь его нужно включить вручную.
PUT megacorp/_mapping/employee/
{
"properties": {
"interests": {
"type": "text",
"fielddata": true
}
}
}
Что-то вроде Group By: например, узнать самые популярные хобби среди сотрудников:
GET /megacorp/employee/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
},
Как видно из вывода, каждый интерес отсортирован по количеству людей:
{
...
"hits": { ... },
"aggregations": {
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "forestry",
"doc_count": 1
},
{
"key": "sports",
"doc_count": 1
}
]
}
}
}
Поле aggs также можно использовать как подзапрос к полю запроса. Такие как:
GET /megacorp/employee/_search
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}
Также поддерживаются иерархические сводки, такие как запрос среднего возраста сотрудников по каждому интересу:
GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}
3. Распределенные функции
Elasticsearch максимально скрывает сложность распределенных систем. Вот некоторые из действий, которые автоматически выполняются в фоновом режиме:
- Распределяйте документы по разным контейнерам или сегментам, документы могут храниться в одном или нескольких узлах
- Эти сегменты равномерно распределяются по узлам кластера, чтобы сбалансировать нагрузку на процесс индексации и поиска.
- Каждый сегмент реплицируется для поддержки избыточности данных, предотвращая потерю данных из-за аппаратного сбоя.
- Направлять запросы от любого узла в кластере к узлу, содержащему соответствующие данные.
- Беспрепятственно интегрируйте новые узлы по мере роста кластера, переназначайте сегменты для восстановления от случайных узлов.