В этом уроке мы познакомимся с анализаторами и почему они необходимы для текстового поиска. Допустим, у нас есть документ, содержащий следующую информацию:
{
"date": "2017/02/01",
"desc": "В Москве все выходные будут дожди"
}
Если мы хотим найти документы, содержащие слово Москва, мы можем запустить SQL-запрос, как показано здесь:
select * from news where desc like '%Москва%'
Эта функциональность очень ограничена и никогда не бывает достаточной для реальных текстовых поисковых запросов. Например, если пользователь ищет прогноз погоды в Москве, он будет запрашивать то же самое на человеческом языке, используя что-то вроде дождь в Москве
. Поскольку SQL может найти только точные фразы, а документ не содержит слова дождь
, запрос не будет возвращаться с каким-либо результатом.
Elasticsearch — полнотекстовая поисковая система и предназначена для обработки таких запросов. Прежде чем документы будут проиндексированы в Elasticsearch, будут также проанализированы поля в документе. Анализ данных разбивает текстовые фразы на отдельные термины, и в зависимости от используемого анализатора слова сводятся к их корневым формам. Следующий пример сделает его более понятным. Elasticsearch предоставляет API анализа, чтобы проверить, как он анализирует текст внутри. Посмотрим, что произойдет, когда мы проанализируем документ о Москве, который содержит текст В Москве все выходные будут дожди
:
GET _analyze?analyzer=russian&text=%D0%92%2B%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B5%2B%D0%B2%D1%81%D0%B5%2B%D0%B2%D1%8B%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B5%2B%D0%B1%D1%83%D0%B4%D1%83%D1%82%2B%D0%B4%D0%BE%D0%B6%D0%B4%D0%B8
Ответ API анализа представляет собой список токенов, как показано ниже:
{ "tokens": [ { "token": "москв", "start_offset": 2, "end_offset": 8, "type": "<ALPHANUM>", "position": 1 }, { "token": "выходн", "start_offset": 13, "end_offset": 21, "type": "<ALPHANUM>", "position": 3 }, { "token": "будут", "start_offset": 22, "end_offset": 27, "type": "<ALPHANUM>", "position": 4 }, { "token": "дожд", "start_offset": 28, "end_offset": 33, "type": "<ALPHANUM>", "position": 5 } ] }
Текст разбиваются на четыре лексемы: москва
, выходные
, будут
и дожди
, и так как мы использовали анализатор русского языка, эти термины также сводятся к их корневым формам (москв , выходн, будут, дожд). Токены, которые вы видите в предыдущем ответе, затем сохраняются в инвертированном индексе. В ответе наряду с токеном информация о положении и смещении также сохраняется для поддержки поиска фразы.
Подобно тому, как анализируются текстовые поля в документе при индексировании, также анализируется текст в запросе. Возьмем пример: когда пользователь запрашивает, дождь в Москве
он проходит аналогичный процесс анализа. Мы также можем использовать _analyze
API, чтобы посмотреть, как Elasticsearch обработает поисковую фразу:
GET _analyze?analyzer=russian&text=%D0%B4%D0%BE%D0%B6%D0%B4%D1%8C%2B%D0%B2%2B%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B5
Отклик анализа показан здесь:
{ "tokens": [ { "token": "дожд", "start_offset": 0, "end_offset": 5, "type": "<ALPHANUM>", "position": 0 }, { "token": "москв", "start_offset": 8, "end_offset": 14, "type": "<ALPHANUM>", "position": 2 } ] }
Из предыдущего ответа вы можете видеть, что запрос дождь в Москве
разбит на "дожд"
и "москв"
. Используя токены, Elasticsearch пытается найти документы в инвертированном индексе. По умолчанию один и тот же анализатор используется для индексирования и запросов.
Если анализатор не задан при маппинге, все текстовые поля анализируются с помощью стандартного анализатора. Если вам нужен анализатор, специфичный для языка, как показано в предыдущем примере, мы можем указать анализатор в схеме. Мы можем настроить анализатор поля desc
на использование анализатора русского языка, как показано ниже:
PUT example3/_mapping/weather { "properties": { "desc": { "type": "text", "analyzer": "russian" } } }
Elasticsearch поддерживает множество анализаторов из коробки. По умолчанию используется стандартный анализатор. Вы можете проверить, как работает каждый анализатор с помощью API анализа. Полный список всех анализаторов, поддерживаемых Elasticsearch, можно найти по следующей ссылке:
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-analyzers.html