Буква "ё" совсем не важна... Завтра похолодает и мы все передохнем от жары... |
Иногда я завидую англоязычным программистам. Например, на клавиатуре им не надо переключать раскладку. А ещё у них нет буквы "Ё"! Буква "Ё" - это очень своенравная особа. Она обязательна только в собственных именах, а в остальных случаях употребление "Ё" или "Е" определяется выбором автора текста. Но при этом пользователя, который ищет по тексту, не заботит, что написал автор - "Ё" или "Е". А какая ему разница? Программа должна найти!
Посмотрим, как Elasticsearch решит эту проблему.
Попытка №1. Анализатор "russian"
В Elasticsearch есть анализаторы, которые преобразуют исходный текст в набор токенов. Среди стандартных анализаторов есть целый набор анализаторов, предназначенных для анализа конкретного языка. Например, русского - "russian".
Создаем индекс "test" и маппируем ему поле "fairytale" с анализатором "russian":
В индексе "test" создаем новый документ:PUT http://localhost:9200/test { "mappings": { "properties": { "fairytale": {"type": "text", "analyzer": "russian" } } } }
Поиск по точному совпадению по слову "растёт"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": [ "Ё => Е", "ё => е", "й => и" ]
и переиндексировать документ
Добрый день, подскажите пожалуйста, данный аналайзер будет влиять на сортировку?
ОтветитьУдалить