| Буква "ё" совсем не важна... Завтра похолодает и мы все передохнем от жары... |
Иногда я завидую англоязычным программистам. Например, на клавиатуре им не надо переключать раскладку. А ещё у них нет буквы "Ё"! Буква "Ё" - это очень своенравная особа. Она обязательна только в собственных именах, а в остальных случаях употребление "Ё" или "Е" определяется выбором автора текста. Но при этом пользователя, который ищет по тексту, не заботит, что написал автор - "Ё" или "Е". А какая ему разница? Программа должна найти!
Посмотрим, как Elasticsearch решит эту проблему.
Попытка №1. Анализатор "russian"
В Elasticsearch есть анализаторы, которые преобразуют исходный текст в набор токенов. Среди стандартных анализаторов есть целый набор анализаторов, предназначенных для анализа конкретного языка. Например, русского - "russian".
Создаем индекс "test" и маппируем ему поле "fairytale" с анализатором "russian":
PUT http://localhost:9200/test
{
"mappings": {
"properties": {
"fairytale": {"type": "text",
"analyzer": "russian"
}
}
}
}В индексе "test" создаем новый документ:POST http://localhost:9200/test/_doc
{"fairytale": "В лесу растёт дуб"}Поиск по точному совпадению по слову "растёт"POST http://localhost:9200/test/_search
{"query": {"match": {"fairytale": "растёт"}}}находит наш документ.А вот поиск по слову "растет"
POST http://localhost:9200/test/_search
{"query": {"match": {"fairytale": "растет"}}}ни находит ни чего.Вот вам и "русский" анализатор! Явно делали его нерусские...
Попытка №2. Свой анализатор
Теперь при создании индекса опишем свой анализатор "e_ru" на основе стандартного анализатора "russian", который для нашего поля "fairytale" преобразует "Ё" в "Е":
PUT http://localhost:9200/test_e
{
"settings": {
"analysis": {
"filter": {
"ru_stop": {
"type": "stop",
"stopwords": "_russian_"
},
"ru_stemmer": {
"type": "stemmer",
"language": "russian"
}
},
"char_filter": {
"e_char_filter": {
"type": "mapping",
"mappings": [ "Ё => Е", "ё => е" ]
}
},
"analyzer": {
"e_ru": {
"tokenizer": "standard",
"filter": [
"lowercase",
"ru_stop",
"ru_stemmer"
],
"char_filter": ["e_char_filter"]
}
}
}
},
"mappings": {
"properties": {
"fairytale": {
"type": "text",
"analyzer": "e_ru"
}
}
}
}В индексе "test_e" создаем такой же документ как в "test":
POST http://localhost:9200/test_e/_doc
{"fairytale": "В лесу растёт дуб"}И пытаемся искать. Поиск по слову "растёт"POST http://localhost:9200/test_e/_search
{"query": {"match": {"fairytale": "растёт"}}}находит наш документ.И поиск по слову "растет"
POST http://localhost:9200/test_e/_search
{"query": {"match": {"fairytale": "растет"}}}тоже находит наш документ.Как видим, грамотно настроенный "char_filter" в анализаторе может значительно усовершенствовать поиск. Например, приручит букву "Ё", уберет из строки не нужные HTML-тэги или улучшит отчет о прибыли заменив в нем символ ₽ на €.
Можете подсказать, как сделать тоже самое с яйцо, яицо?
ОтветитьУдалитьСамое простое, что приходит в голову - добавить "й" в mappings:
Удалить"mappings": [ "Ё => Е", "ё => е" ] заменить на "mappings": [ "Ё => Е", "ё => е", "й => и" ]
и переиндексировать документ
Добрый день, подскажите пожалуйста, данный аналайзер будет влиять на сортировку?
ОтветитьУдалить