Рубрики
Без рубрики

Краткое введение в полнотекстовый поиск с помощью ElasticSearch

В этой статье исследуется API REST Elasticsearch и выполняются основные операции с использованием HTTP-запросов.

Автор оригинала: baeldung.

1. Обзор

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

ElasticSearch-это поисковая система , основанная на Apache Lucene , бесплатной библиотеке программного обеспечения для поиска информации с открытым исходным кодом. Он предоставляет распределенную полнотекстовую поисковую систему с веб-интерфейсом HTTP и документами JSON без схем.

В этой статье рассматривается API REST ElasticSearch и демонстрируются основные операции, использующие только HTTP-запросы.

2. Настройка

Чтобы установить ElasticSearch на свой компьютер, пожалуйста, обратитесь к официальному руководству по установке .

Restful API работает на порту 9200. Давайте проверим, правильно ли он работает, используя следующую команду curl:

curl -XGET 'http://localhost:9200/'

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

{
  "name": "NaIlQWU",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "enkBkWqqQrS0vp_NXmjQMQ",
  "version": {
    "number": "5.1.2",
    "build_hash": "c8c4c16",
    "build_date": "2017-01-11T20:18:39.146Z",
    "build_snapshot": false,
    "lucene_version": "6.3.0"
  },
  "tagline": "You Know, for Search"
}

3. Индексирование Документов

ElasticSearch ориентирован на документы. Он хранит и индексирует документы. Индексирование создает или обновляет документы. После индексирования вы можете искать, сортировать и фильтровать полные документы, а не строки столбчатых данных. Это принципиально иной подход к данным, и это одна из причин, по которой ElasticSearch может выполнять сложный полнотекстовый поиск.

Документы представлены в виде объектов JSON. Сериализация JSON поддерживается большинством языков программирования и стала стандартным форматом, используемым движением NoSQL. Она проста, лаконична и легко читается.

Мы собираемся использовать следующие случайные записи для выполнения нашего полнотекстового поиска:

{
  "title": "He went",
  "random_text": "He went such dare good fact. The small own seven saved man age."
}

{
  "title": "He oppose",
  "random_text": 
    "He oppose at thrown desire of no. \
      Announcing impression unaffected day his are unreserved indulgence."
}

{
  "title": "Repulsive questions",
  "random_text": "Repulsive questions contented him few extensive supported."
}

{
  "title": "Old education",
  "random_text": "Old education him departure any arranging one prevailed."
}

Прежде чем мы сможем проиндексировать документ, нам нужно решить, где его хранить. Возможно иметь несколько индексов, которые, в свою очередь, содержат несколько типов. Эти типы содержат несколько документов, и каждый документ содержит несколько полей.

Мы будем хранить ваши документы по следующей схеме:

текст : Имя индекса. статья
: Название типа. id
: Идентификатор этого конкретного примера ввода текста.

Чтобы добавить документ, мы собираемся выполнить следующую команду:

curl -XPUT 'localhost:9200/text/article/1?pretty'
  -H 'Content-Type: application/json' -d '
{
  "title": "He went",
  "random_text": 
    "He went such dare good fact. The small own seven saved man age."
}'

Здесь мы используем id=1 , мы можем добавлять другие записи, используя ту же команду и увеличенный идентификатор.

4. Извлечение Документов

После добавления всех наших документов мы можем проверить, сколько документов, используя следующую команду, у нас есть в кластере:

curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
  "query": {
    "match_all": {}
  }
}'

Кроме того, мы можем получить документ, используя его идентификатор, с помощью следующей команды:

curl -XGET 'localhost:9200/text/article/1?pretty'

И мы должны получить следующий ответ из эластичного поиска:

{
  "_index": "text",
  "_type": "article",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "title": "He went",
    "random_text": 
      "He went such dare good fact. The small own seven saved man age."
  }
}

Как мы видим, этот ответ соответствует записи, добавленной с использованием идентификатора 1.

5. Запрос Документов

ХОРОШО, давайте выполним полнотекстовый поиск с помощью следующей команды:

curl -XGET 'localhost:9200/text/article/_search?pretty' 
  -H 'Content-Type: application/json' -d '
{
  "query": {
    "match": {
      "random_text": "him departure"
    }
  }
}'

И мы получаем следующий результат:

{
  "took": 32,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1.4513469,
    "hits": [
      {
        "_index": "text",
        "_type": "article",
        "_id": "4",
        "_score": 1.4513469,
        "_source": {
          "title": "Old education",
          "random_text": "Old education him departure any arranging one prevailed."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "3",
        "_score": 0.28582606,
        "_source": {
          "title": "Repulsive questions",
          "random_text": "Repulsive questions contented him few extensive supported."
        }
      }
    ]
  }
}

Как мы видим, мы ищем “его уход” и получаем два результата с разными оценками. Первый результат очевиден, потому что в тексте есть выполненный поиск внутри него, и, как мы видим, у нас есть оценка 1.4513469 .

Второй результат получен, потому что целевой документ содержит слово “он”.

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

6. Нечеткий Поиск

Нечеткое сопоставление рассматривает два слова, которые “нечетко” похожи, как если бы они были одним и тем же словом. Во-первых, нам нужно определить, что мы подразумеваем под нечеткостью.

Elasticsearch поддерживает максимальное расстояние редактирования, указанное с помощью параметра размытость, равное 2. Параметр размытости может быть установлен в значение АВТО, что приводит к следующим максимальным расстояниям редактирования:

  • 0 для строк из одного или двух символов
  • 1 для строк из трех, четырех или пяти символов
  • 2 для строк длиной более пяти символов

вы можете обнаружить, что расстояние редактирования 2 возвращает результаты, которые, по-видимому, не связаны.

Вы можете получить лучшие результаты и лучшую производительность при максимальной нечеткости 1. Расстояние относится к расстоянию Левенштейна, которое является строковой метрикой для измерения разницы между двумя последовательностями. Неофициально расстояние Левенштейна между двумя словами-это минимальное количество односимвольных правок.

Хорошо, давайте проведем наш поиск с нечеткостью:

curl -XGET 'localhost:9200/text/article/_search?pretty' -H 'Content-Type: application/json' -d' 
{ 
  "query": 
  { 
    "match": 
    { 
      "random_text": 
      {
        "query": "him departure",
        "fuzziness": "2"
      }
    } 
  } 
}'

И вот результат:

{
  "took": 88,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 1.5834423,
    "hits": [
      {
        "_index": "text",
        "_type": "article",
        "_id": "4",
        "_score": 1.4513469,
        "_source": {
          "title": "Old education",
          "random_text": "Old education him departure any arranging one prevailed."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "2",
        "_score": 0.41093433,
        "_source": {
          "title": "He oppose",
          "random_text":
            "He oppose at thrown desire of no. 
              \ Announcing impression unaffected day his are unreserved indulgence."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "3",
        "_score": 0.2876821,
        "_source": {
          "title": "Repulsive questions",
          "random_text": "Repulsive questions contented him few extensive supported."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "title": "He went",
          "random_text": "He went such dare good fact. The small own seven saved man age."
        }
      }
    ]
  }
}'

Как мы видим, нечеткость дает нам больше результатов.

Нам нужно осторожно использовать нечеткость, потому что она имеет тенденцию извлекать результаты, которые выглядят несвязанными.

7. Заключение

В этом кратком руководстве мы сосредоточились на индексировании документов и запросе Elasticsearch для полнотекстового поиска непосредственно через REST API .

У нас, конечно, есть API, доступные для нескольких языков программирования, когда нам это необходимо, но API по – прежнему довольно удобен и не зависит от языка.