Elasticsearch: гибкая поисковая система

Те, кому нужен мощный полнотекстовый поиск, обычно выбирают Apache Solr. Хотя этот проект по-прежнему является хорошим выбором, с 2010 года появилась интересная альтернатива: Elasticsearch. Как и Solr, Elasticsearch основан на Apache Lucene, но предлагает другие возможности. Здесь представлен обзор возможностей поискового сервера и учебник по Elasticsearch для реализации полнотекстового поиска в вашем собственном проекте.

Что такое Elasticsearch?

Elasticsearch относится к наиболее важным полнотекстовым поисковым системам в интернете. Крупные компании также используют это программное обеспечение — Facebook, например, успешно работает с Elasticsearch уже несколько лет, а GitHub, Netflix и SoundCloud также полагаются на успешную поисковую систему.

Учитывая объем информации на некоторых сайтах, высокий уровень удобства для пользователей может быть гарантирован только при использовании функционального полнотекстового поиска. Если вы не хотите использовать Google или Bing, чтобы предложить посетителям вашего сайта функцию поиска, вам придется встроить вместо этого собственную функцию поиска. Это возможно с помощью Elasticsearch. Этот проект с открытым исходным кодом основан на свободно распространяемом Apache Lucene.

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

Хотя Lucene дает вам полную свободу действий в отношении того, где и как использовать полнотекстовый поиск, это также означает, что вам придется начинать с нуля. Elasticsearch, с другой стороны, позволяет вам начать работу быстрее. С помощью Elasticsearch можно за короткое время создать стабильный поисковый сервер, который также легко распределить на несколько машин.

Несколько узлов (различных серверов) объединяются в кластер. При этом используется так называемый метод «шардинга». Elasticsearch разбивает индекс и распределяет отдельные части (shards) по нескольким узлам. Это также распределяет вычислительную нагрузку — для больших проектов полнотекстовый поиск работает гораздо стабильнее.

Elaticsearch — как и Lucene — основан на объектно-ориентированном языке программирования Java. Поисковая система выводит результаты поиска в формате JSON и предоставляет их через веб-сервис REST. API позволяет легко интегрировать функцию поиска в веб-сайт.

Кроме того, вместе с Kibana, beats и logstash — в совокупности известные как Elastic-Stack — Elasticsearch предлагает практичные дополнительные сервисы, с помощью которых можно анализировать полнотекстовый поиск. Elastic, компания, стоящая за разработкой Elasticsearch, также предлагает платные услуги — например, облачный хостинг.

Что предлагает Elasticsearch, чего не предлагает Google и другие?

Google уже является успешным вариантом — и вы можете легко интегрировать его популярную функцию поиска в свой собственный сайт. Так зачем же выполнять дополнительную работу по созданию собственной поисковой системы с помощью Elasticsearch? Один из возможных ответов заключается в том, что при использовании Google Custom Search (GCS) вы зависите от Google и вынуждены разрешить рекламу (по крайней мере, в бесплатной версии) в результатах поиска. Однако в Elasticsearch код с открытым исходным кодом, и если вы создали функцию полнотекстового поиска, она принадлежит вам — вы ни от кого не зависите.

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

Elasticsearch против Apache Solr: Каковы ключевые различия?

И Elasticsearch, и Apache Solr основаны на Lucene, но были разработаны как независимые программы. Тем не менее, многие пользователи задаются вопросом, какой проект выбрать. Хотя Elasticsearch немного моложе и, в отличие от Solr, не поддерживается опытным сообществом Apache, он стал очень популярным. Основная причина этого заключается в том, что он проще в реализации. Кроме того, Elasticsearch особенно популярен благодаря тому, как он работает с динамическими данными. Благодаря специальной процедуре кэширования Elasticsearch гарантирует, что изменения не нужно вносить во весь глобальный кэш. Вместо этого достаточно изменить небольшой сегмент. Это делает Elasticsearch более гибким.

Однако, в конечном счете, решение часто связано только с различными подходами к открытому исходному коду. Solr полностью придерживается идеи Apache Software Foundation «Сообщество над кодом». Каждый вклад в код воспринимается серьезно, и сообщество вместе решает, какие дополнения и улучшения войдут в окончательный вариант кода. Иначе обстоит дело с дальнейшим развитием Elasticsearch. Этот проект также является проектом с открытым исходным кодом и предлагается под свободной лицензией Apache — однако только команда Elastic определяет, какие изменения войдут в код. Некоторым разработчикам это не нравится, и поэтому они выбирают Solr.

Учебник по Elasticsearch

Приступая к работе с Elasticsearch, следует начать со знания нескольких основных терминов. Стоит упомянуть информационную структуру:

  • Индекс: Поисковый запрос в Elasticsearch никогда не обращается к самому содержимому, а всегда к индексу. Все содержимое всех документов хранится в этом файле и уже подготовлено, поэтому поиск занимает совсем немного времени. Это инвертированный индекс: Для каждого поискового термина указывается место, где этот термин может быть найден.
     
  • Документ: Исходящими для индекса являются документы, в которых встречаются данные. Это не обязательно должны быть полные тексты (например, статьи в блогах) — достаточно просто файлов с информацией.
     
  • Поле: Документ состоит из нескольких полей. Помимо собственно поля содержимого, к документу относятся и другие метаданные. С помощью Elasticsearch вы можете искать метаданные об авторе или времени создания документа.

Когда мы говорим об обработке данных, мы в первую очередь имеем в виду токенизацию. Алгоритм создает отдельные термины из полного текста. Для машины не существует такого понятия, как слова. Вместо этого текст состоит из длинной строки, и буква имеет для компьютера то же значение, что и пробел. Для того чтобы текст был отформатирован, его необходимо сначала разбить на лексемы. Например, пробельные символы, пробелы и дефисы считаются маркерами слов. Кроме того, текст должен быть стандартизирован. Слова пишутся в едином строчном регистре, а знаки препинания игнорируются. Elasticsearch перенял все эти методы у Apache Lucene.

Примечание

В следующем руководстве мы будем работать с версией 6.3.0 Elasticsearch. Если вы используете другую версию, некоторые примеры кода или инструкции могут работать по-другому.

Установка

Файлы, необходимые для Elasticsearch, находятся в свободном доступе на официальном сайте Elastic. Файлы предлагаются там в виде пакетов ZIP или tar.gz, поэтому их можно легко установить под Linux и Mac с помощью консоли.

Примечание

Elastic предлагает Elasticsearch в двух различных пакетах. Стандартная версия также включает платные функции, которые вы можете опробовать в пробной версии в течение некоторого времени. Такие пакеты, помеченные OSS (open source software), содержат только бесплатные компоненты, выпущенные по лицензии Apache 2.0.

Для ZIP:

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.zip
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.zip.sha512
shasum -a 512 -c elasticsearch-oss-6.3.0.zip.sha512 
unzip elasticsearch-oss-6.3.0.zip
cd elasticsearch-6.3.0

Для tar.gz:

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.tar.gz
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-6.3.0.tar.gz.sha512
shasum -a 512 -c elasticsearch-oss-6.3.0.tar.gz.sha512 
tar -xzf elasticsearch-oss-6.3.0.tar.gz
cd elasticsearch-6.3.0

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

ZIP-архив также можно скачать и использовать для установки в Windows, поскольку пакет содержит пакетный файл, который можно запустить. В качестве альтернативы Elastic теперь также предоставляет программу установки MSI, но она все еще находится на стадии бета-тестирования. Установочный файл последнего содержит графический интерфейс, который точно проведет вас через установку.

Примечание

Поскольку Elasticsearch основан на Java, этот язык программирования также должен быть установлен в вашей системе. Бесплатно скачайте Java Development Kit (JDK) с официального сайта.

Теперь запустите Elasticsearch из консоли, перейдя в соответствующую папку bin и набрав «elasticsearch» — независимо от того, используете ли вы Linux, Mac или Windows. Затем откройте браузер по своему выбору и вызовите следующий порт localhost:

localhost

. Если вы правильно установили Elasticsearch и Java настроена правильно, то теперь вы должны иметь доступ к полнотекстовому поиску.

Вы можете взаимодействовать с Elasticsearch через REST API, для чего вам также понадобится соответствующий клиент. Kibana

является хорошим выбором (также бесплатное предложение с открытым исходным кодом от Elastic). Эта программа позволяет использовать Elasticsearch прямо в браузере. Для этого достаточно зайти на localhost, чтобы получить доступ к графическому интерфейсу пользователя. Как правильно установить и настроить Kibana, описано в нашем руководстве|. В Kibana и любом другом клиенте вы можете использовать HTTP-методы PUT, GET, POST и DELETE для отправки команд вашему полнотекстовому поиску.

Индекс

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

POST bibliography/novels
{
"author": "Isabel Allende",
"title": "La casa de los espíritus",
"year": "1982"
}

Если вы хотите использовать ввод таким образом, вы должны использовать консоль Kibana. Однако, если вы не хотите использовать это программное обеспечение, вы также можете использовать cURL в качестве альтернативы. Вместо предыдущей команды в командной строке нужно ввести следующую:

curl -XPOST http://localhost:9200/bibliography/novels -H "Content-Type: application/json" -d '{"author": "Isabel Allende", "title": "La casa de los espíritus", "year": "1982"}'

Далее мы покажем код только для Kibana — но его можно легко перенести в синтаксис cURL.

Elasticsearch должен, если вы все ввели правильно, вернуть следующую информацию в начале сообщения:

{
  "_index": "bibliography",
  "_type": "novels",
  "_id": "AKKKIWQBZat9Vd0ET6N1",
  "_version": 1,
  "result": "created",
}

На этом этапе станет ясно, что Elasticsearch сейчас находит индекс с именем «библиография» и типом «романы». Поскольку мы использовали метод POST, Elasticsearch автоматически сгенерировал уникальный идентификатор для нашей записи. В настоящее время запись находится в первой версии и была недавно создана.

Обратите внимание на .

Один тип (_type) был своего рода подкатегорией в Elasticsearch. Можно было собрать несколько типов под одним индексом. Однако это приводило к различным проблемам, поэтому в настоящее время Elastic планирует больше не использовать такие типы. В версии 6.x _type все еще включен, но объединить несколько типов под одним индексом уже невозможно. Начиная с версии 7.0 планируется полностью удалить типы, как объясняют разработчики в своем блоге.

Вы также можете использовать PUT, чтобы дать вашей записи очень специфический ID. Он определяется в первой строке кода. Вам также понадобится PUT, если вы хотите изменить существующую запись.

PUT bibliography/novels/1
{
"author": "William Gibson",
"title": "Neuromancer",
"year": "1984"
}

Следующий вывод очень похож на тот, который мы получаем при использовании метода POST, но Elasticsearch дает нам ID, который мы задали записи в первой строке. Порядок указания всегда такой _index/_type/_id.

{
  "_index": "bibliography",
  "_type": "novels",
  "_id": "1",
  "_version": 1,
  "result": "created",
}

С помощью команды PUT и уникального ID мы также можем изменять записи:

PUT bibliography/novels/1
{
"author": "William Gibson",
"title": "Count Zero",
"year": "1986"
}

Поскольку запись с ID 1 уже существует, Elasticsearch только изменяет ее, а не создает новую. Это также отражено в выводе:

{
  "_index": "bibliography",
  "_type": "novels",
  "_id": "1",
  "_version": 2,
  "result": "updated",
}

Номер версии увеличился до 2, и в результате мы получаем «обновлено» вместо «создано». Конечно, вы можете сделать то же самое с идентификатором, созданным Elasticsearch случайным образом — но из-за длины и порядка символов работа потребует гораздо больше усилий. Эта процедура также означает, что Elasticsearch просто перезапишет запись, если, например, вы запутаетесь в номерах ID. Чтобы избежать случайной перезаписи, вы можете использовать конечную точку _create:

PUT bibliography/novels/1/_create
{
"author": "Mary Shelley",
"title": "Frankenstein; or, The Modern Prometheus",
"year": "1818"
}

Поскольку запись с ID 1 уже существует в индексе, будет выдано сообщение об ошибке.

Если вы вносите изменения в запись, как описано выше, вы создаете совершенно новую запись и поэтому должны также полностью ввести все записи. Вы можете только интегрировать изменения в существующую запись. Для этого используйте конечную точку _update:

POST bibliography/novels/1/_update
{
"doc": {
  "author": "Franz Kafka",
"genre": "Horror"
  }
}

Теперь мы добавили в запись дополнительное поле и изменили существующее поле, не удаляя остальные — но только на переднем плане. Однако в фоновом режиме Elasticsearch создал полную запись, но вставил существующее содержимое самостоятельно.

В принципе, до сих пор мы просто записывали запись в базу данных и поэтому можем получить ее напрямую. Для этого мы используем метод GET.

GET bibliography/novels/1

Можно также просто отобразить запись в браузере:

http://localhost:9200/bibliography/novels/1

В выводе Elasticsearch показывает нам все детали нашей записи:

{
  "_index": "bibliography",
  "_type": "novels",
  "_id": "1",
  "_version": 2,
  "found": true,
  "_source": {
    "author": "William Gibson",
    "title": “Count Zero",
    "year": "1984"
  }
}

В дополнение к этой информации вы найдете поля документа в разделе _source. Elasticsearch также сообщает нам, что запись была найдена. Если вы попытаетесь загрузить несуществующую запись, сообщение об ошибке не появится. Вместо этого Elasticsearch сообщает «found»: false, и в разделе _source нет записей.

У вас также есть возможность извлечь из базы данных только определенную информацию. Предположим, что вы храните в индексе не только библиографические данные, но и полный текст каждого записанного романа. Это также будет отображаться с помощью простого GET-запроса. Предположим, что в настоящее время вас интересует только имя автора и название произведения — тогда вы можете только специально запросить это:

GET bibliography/novels/1?_source=author,title

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

GET bibliography/novels/1/_source

Предположим, вы хотите найти в индексе не одну единственную запись, а сразу несколько. В Elasticsearch реализована точка _mget-endpoint (для multi-get). Если вы используете его, укажите массив из нескольких идентификаторов:

GET bibliography/novels/_mget
{
  "ids": ["1", "2", "3"]
}

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

Подобно загрузке записи, ее удаление также работает. Однако вы работаете с DELETE вместо GET:

DELETE /bibliography/novels/1

В следующем выводе Elasticsearch сообщает, что нашел запись под указанным ID:

{
  "_index": "bibliography",
  "_type": "novels",
  "_id": "1",
  "_version": 5,
  "result": "deleted",
}

Программа также увеличивает номер версии на единицу. Для этого есть две причины:

  1. Elasticsearch только помечает запись как удаленную и не удаляет ее непосредственно с жесткого диска. Запись исчезнет только в ходе дальнейшего индексирования.
     
  2. При работе с распределенными индексами на нескольких узлах подробный контроль версий чрезвычайно важен. Именно поэтому Elasticsearch отмечает каждое изменение как новую версию — включая запрос на удаление.

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

PUT bibliography/novels/1?version=3
{
"author": "Marcel Proust",
"title": " À la recherche du temps perdu",
"year": "1927"
}

Вы можете не только вызывать несколько записей одновременно, но и создавать или удалять несколько записей с помощью команд _bulk. Elasticsearch использует для этого немного измененный синтаксис.

POST bibliography/novels/_bulk
{"delete": {"_id": "1"}}
{"create": {"_id": "1"}}
{"author": "Johann Wolfgang von Goethe", "title": "Die Leiden des jungen Werther", "year": "1774"}
{"create": {"_id": "2"}}
{"author": "Umberto Eco", "title": "Il nome della rosa", "year": "1980"}
{"create": {"_id": "3"}}
{"author": "Margaret Atwood", "title": "The Handmaid’s Tale", "year": "1985"}

Каждая команда имеет свою собственную строку. Сначала вы указываете, какое действие должно быть выполнено (создать, проиндексировать, обновить, удалить). Вы также указываете, какую запись вы хотите создать и где. Также можно работать с несколькими индексами с помощью такого массового оператора. Для этого нужно оставить путь к POST пустым и назначить отдельный путь для каждого действия. При создании записей вы также должны указать тело запроса в новой строке. Оно содержит содержимое записи. Оператор DELETE не требует указания тела запроса, поскольку удаляется вся запись.

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

GET bibliography/novels/_mapping

Всем полям присвоены типы text и keyword. Elasticsearch знает 6 основных типов данных и еще больше специальных полей. Эти 6 основных типов частично подразделяются на дополнительные подкатегории:

  • строка: Включает в себя как текст, так и ключевое слово. Хотя ключевые слова считаются точным соответствием, Elasticsearch предполагает, что текст должен быть проанализирован, прежде чем его можно будет использовать.
     
  • числовой: Elasticsearch знает различные числовые значения, которые отличаются, прежде всего, областью применения. Например, если тип byte может принимать значения от -128 до 127, то long имеет диапазон -263 до 263-1.
     
  • дата: Дата может быть указана либо с точностью до дня, либо со временем. Можно также указать дату в виде времени Unix: секунды или миллисекунды с 1. 1. 1970 года.
  • boolean: Поля, отформатированные как boolean, могут иметь значение true или false.
     
  • двоичный: В этих полях можно хранить двоичные данные. Для их передачи используйте кодировку Base64.
     
  • диапазон: Используется для указания диапазона. Это может быть диапазон между двумя числовыми значениями, двумя данными или даже между двумя IP-адресами.

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

  • Токенизация: Из текста выделяются отдельные лексемы. Они могут включать отдельные слова, а также фиксированные термины из нескольких слов.
     
  • Нормализация: Токены нормализуются путем перевода их в нижний регистр и сокращения до корневой формы.

Если вы включили документ в индекс и правильно выполнили маппинг, все содержимое документа будет правильно включено в инвертированный индекс. Чтобы использовать маппинг самостоятельно, необходимо создать совершенно новый индекс. Сопоставление существующих полей невозможно.

PUT bibliography
{
  "mappings": {
    "novels": {
      "properties": {
        "author": {
          "type": "text",
          "analyzer": "simple"
        },
        "title": {
          "type": "text",
          "analyzer": "standard"
        },
        "year": {
          "type": "date",
          "format": "year"
        }
      }
    }
}
}

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

Поиск

В предыдущем разделе мы использовали Elasticsearch и его индекс в основном в качестве базы данных. Однако реальным преимуществом Elasticsearch является его полнотекстовый поиск. Это означает, что вместо того, чтобы вводить идентификатор документа и находить запись, мы теперь настроим Elasticsearch так, чтобы можно было искать конкретный контент. Для использования поисковой системы программа предоставила конечную точку _search. Вы можете использовать ее в сочетании с методом GET для отображения всех записей, например:

GET bibliography/novels/_search
Факт

Для более сложных поисковых запросов _search использует тело в скобках. Однако некоторые HTTP-серверы не предоставляют такой возможности для метода GET. Поэтому разработчики решили, что такие запросы также работают как POST.

Вы также можете оставить путь пустым для поиска по всем существующим индексам. В выводе вы найдете интересную информацию в разделе hits:

"hits": {
  "total": 3,
  "max_score": 1,
  "hits": [
    {
      "_index": "bibliography",
      "_type": "novels",
      "_id": "2",
      "_score": 1,
      "_source": {
        "author": "Umberto Eco",
        "title": "Il nome della rosa",
        "year": "1980"
      }
    },
  ],
  }
}

Все остальные записи в нашем индексе также перечислены в выводе (и опущены здесь только для наглядности). Обратная связь от Elasticsearch предоставляет нам не только фактическое содержимое, но и две дополнительные информации, которые могут помочь нам разобраться в полнотекстовом поиске:

  • хиты: Каждая запись, соответствующая критериям поиска, считается попаданием в Elasticsearch. Программа также отображает количество попаданий. Поскольку в нашем примере в индексе 3 записи, и все они могут быть отображены, применяется значение «всего»: 3.
     
  • Оценка: В виде оценки Elasticsearch показывает, насколько релевантна запись по отношению к нашему поисковому запросу. Поскольку в нашем примере мы просто искали все посты, все они имеют одинаковый балл 1, и в результатах поиска записи сортируются в порядке убывания релевантности.

Кроме того, Elasticsearch предоставляет информацию о том, сколько шардов задействовано в результатах поиска, сколько миллисекунд занял поиск и произошел ли тайм-аут.

Если вы уже видели первые 10 результатов поиска и хотите отобразить только следующие 15, необходимо использовать комбинацию обоих параметров:

  • size: Сколько результатов должен отобразить Elasticsearch?
     
  • from: Сколько записей должна пропустить программа перед их отображением?
GET bibliography/novels/_search?size=15&from=10

Elasticsearch различает два разных типа поиска. С одной стороны, он использует «легкую» версию, а с другой — более сложный вариант, который работает с запросом DSL — специфическим языком поиска. В «легкой» версии вы должны вводить свой поисковый запрос непосредственно в виде простой строки:

GET bibliography/novels/_search?q=atwood

Однако поиск можно осуществлять только в пределах определенного поля:

GET bibliography/novels/_search?q=author:atwood
Факт

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

Если вы хотите объединить несколько критериев поиска, используйте знак плюс (+). Используя знак минус (-), вы исключите определенные критерии. Однако при использовании этих операторов в поисковом запросе необходимо применять процентную кодировку:

GET bibliography/novels/_search?q=%2Bauthor%3Aatwood+%2Btitle%3Ahandmaid

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

Этот вариант поиска хорошо подходит для простых запросов, но с более сложными задачами «lite» версия справится не так легко. Риск ввести ошибку в длинную строку слишком велик. Для этого Elasticsearch предлагает более удобный метод в виде Query DSL. Отправной точкой такого поиска является параметр запроса в сочетании с запросом на соответствие:

GET bibliography/novels/_search
{
  "query": {
    "match": {
"author": "allende"
}
  }
}

Результат показывает нам все записи, которые содержат термин «allende» в поле author. Это также говорит нам о том, что анализ работал в отображении, поскольку Elasticsearch игнорирует верхний и нижний регистр. Чтобы отобразить все записи, можно использовать match_all в дополнение к уже представленному простому варианту:

GET bibliography/novels/_search
{
  "query": {
    "match_all": {}
  }
}

Противоположностью такого поиска является match_none. Elasticsearch также предоставляет возможность поиска в нескольких полях с помощью одного поискового запроса:

GET bibliography/novels/_search
{
  "query": {
    "multi_match": {
      "query": "la",
      "fields": ["author", "title"]
    }
  }
}

Для обеспечения сложных поисковых запросов вы можете комбинировать несколько поисковых терминов и оценивать их по-разному. Вот три из них, доступных вам:

  • обязательно: Поисковый термин должен быть в результате.
  • must_not: Поисковый запрос не должен быть в результатах.
  • должен: Если этот термин появляется, релевантность в результатах поиска повышается.

На практике вы будете комбинировать это с булевым запросом:

GET bibliography/novels/search_
{
  "query": {
"bool": {
    "must": {
      "match": {
        "title": "la"
      }
},
    "must_not": {
      "match": {
        "title": "rabbit"
      }
    },
    "should": {
      "match": {
        "author": "allende"
      }
    }
  }
}
}

Вы также можете расширить поиск, добавив фильтр. Это позволяет указать критерии, ограничивающие результаты поиска:

 GET bibliography/novels/search_
{
  "query": {
"bool": {
    "must": {
      "match": {
        "title": "la"
      }
},
    "filter": {
      "range": {
        "year": {
          "gte": "1950",
          "lt": "2000"
        }
      }
    }
  }
}
}

В предыдущем примере мы связали фильтр со спектром — будут показаны только записи, появившиеся в период с 1950 по 2000 год.

Сводка

С помощью этого инструмента у вас есть все необходимое для реализации полнотекстового поиска в вашем проекте. Однако Elasticsearch предлагает и другие методы для уточнения поиска и его усложнения. Более подробную информацию вы можете найти на официальном сайте Elastic. Если вы хотите расширить полнотекстовый поиск, вы также можете создавать собственные скрипты с помощью других языков, таких как Groovy и Clojure.

Плюсы и минусы Elasticsearch

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

Плюсы

Консы

Открытый исходный код

Elastic в качестве привратника

Быстрый и стабильный

 

Масштабируемый

 

Множество готовых программных модулей (анализатор, полнотекстовый поиск…)

 

Простая реализация благодаря Java, JSON и REST-API

 

Гибкая и динамичная

 

Оцените статью
cdelat.ru
Добавить комментарий