# Как настроить поиск русских слов?

**URL:** https://discuss.elastic.co/t/topic/103999
**Category:** Вопросы на русском языке
**Created:** [October 14, 2017, 2:45pm UTC](https://discuss.elastic.co/t/topic/103999 "2017-10-14T14:45:03Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![FilimonovAP](https://avatars.discourse-cdn.com/v4/letter/f/e36b37/32.png) [@FilimonovAP](https://discuss.elastic.co/u/FilimonovAP)
#### Post date: [October 14, 2017, 2:45pm UTC](https://discuss.elastic.co/t/topic/103999/1 "2017-10-14T14:45:03Z")

</div>

Здравствуйте,  
Есть вопросы по работе и настройке поиска в ES. Сам я в нём не как рыба в воде, так что нужна помощь.

К сути.  
Использую ES 5.4.0  
Создал следующую модель:  
PUT [http://localhost:9200/test\_search](http://localhost:9200/test_search)  
{  
"mappings": {  
"first\_test": {  
"properties": {  
"number" : {  
"type": "keyword"  
},  
"name" : {  
"type": "text",  
"analyzer" : "russian",  
"fields": {  
"raw" : {  
"type": "keyword"  
}  
}  
}  
}  
}  
}  
}

Закинул следующие данные:  
POST [http://localhost:9200/test\_search/first\_test/\_bulk](http://localhost:9200/test_search/first_test/_bulk)  
{ "index": {}}  
{ "name" : "электрообогрева"}  
{ "index": {}}  
{ "name" : "электрообогревом"}  
{ "index": {}}  
{ "name" : "Резервуарное"}  
{ "index": {}}  
{ "name" : "обогреватель"}  
{ "index": {}}  
{ "name" : "стрелецкий"}  
{ "index": {}}  
{ "name" : "листопад"}  
{ "index": {}}  
{ "name" : "tt"}

Пытаемся искать:  
POST [http://localhost:9200/test\_search/first\_test/\_search](http://localhost:9200/test_search/first_test/_search)  
{  
"query" :{  
"match":{  
"name" : {  
"query" : "электрообогрев",  
"operator" : "and"  
}  
}  
}  
}

нет результатов

POST [http://localhost:9200/test\_search/first\_test/\_search](http://localhost:9200/test_search/first_test/_search)  
{  
"query" :{  
"match":{  
"name" : {  
"query" : "обогрев",  
"operator" : "and"  
}  
}  
}  
}

нет результатов

POST [http://localhost:9200/test\_search/first\_test/\_search](http://localhost:9200/test_search/first_test/_search)  
{  
"query" :{  
"match":{  
"name" : {  
"query" : "резервуар",  
"operator" : "and"  
}  
}  
}  
}

нет результатов

При этом если искать иначе (что в принципе не логично)  
{  
"query" :{  
"match":{  
"name" : {  
"query" : "резервуарн",  
"operator" : "and"  
}  
}  
}  
}

то находит запись с name = "резервуарное"

Что я делаю не так и как можно исправит сложившуюся ситуацию.

Спасибо за ответы...

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [October 15, 2017, 4:01pm UTC](https://discuss.elastic.co/t/topic/103999/2 "2017-10-15T16:01:09Z")

</div>

Тут две проблемы - некачественная лемматизация и составные сложные слова.  
`russian` это очень примитивный анализатор, он с русским языком справиться толком не может, отсюда причуды с лемматизацией. Для русского языка надо использовать что-нибудь помощнее, вроде [`hunspell`](https://www.elastic.co/guide/en/elasticsearch/reference/5.6/analysis-hunspell-tokenfilter.html) или [`russian_morphology`](https://github.com/imotov/elasticsearch-analysis-morphology).

Для того, чтобы разбивать составные сложные слова нужен [`decompounder`](https://www.elastic.co/guide/en/elasticsearch/reference/5.6/analysis-compound-word-tokenfilter.html).

---

<div class="post-metadata">

### Author: ![FilimonovAP](https://avatars.discourse-cdn.com/v4/letter/f/e36b37/32.png) [@FilimonovAP](https://discuss.elastic.co/u/FilimonovAP)
#### Post date: [November 3, 2017, 11:01pm UTC](https://discuss.elastic.co/t/topic/103999/3 "2017-11-03T23:01:14Z")

</div>

Спасибо Игорь за ваш ответ.  
Пересмотрел свою модель, поигрался с настройками. Я почему то думал что russian - это тоже самое что и russian\_morphology только встроенное в ES. Оказалось что последний работает гораздо понятнее и лучше.  
Но есть вопрос иного плана.

Если я правильно понял то анализатор при индексировании формирует ключевые слова которые он ассоциирует с данной записью.  
При поиске он вычленяет ключевые слова из поисковой строки и ищет их в ключевых словах и потом выдаёт как результат набор записей которые ответствуют запросу.  
Вопрос следующий: можно как то сделать так что бы поиск по ключевым словам осуществлялся по принципу регулярных выражений?  
Например: Мы проиндексировали такой вот текст "Мама мыла раму". С данным текстом у нас теперь ассоциируются следующие ключевые слова "мама", "рама", "мыл". Можно как то сделать так что бы данный текст находился по запросу "ра\*"?  
Тоесть система ищет среди ключевых слов слово "ра.\*" а не в самом тексте как это происходит при regexp query?  
Надеюсь понятно описал свой вопрос.

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [November 4, 2017, 12:58am UTC](https://discuss.elastic.co/t/topic/103999/4 "2017-11-04T00:58:10Z")

</div>

> [@FilimonovAP](#):
>
> Тоесть система ищет среди ключевых слов слово "ра.\*" а не в самом тексте как это происходит при regexp query?

Я что-то тут не понял, regex ищет по токенам, который анализатор генерирует, а не в самом тексте.

---

<div class="post-metadata">

### Author: ![FilimonovAP](https://avatars.discourse-cdn.com/v4/letter/f/e36b37/32.png) [@FilimonovAP](https://discuss.elastic.co/u/FilimonovAP)
#### Post date: [November 4, 2017, 1:04pm UTC](https://discuss.elastic.co/t/topic/103999/5 "2017-11-04T13:04:10Z")

</div>

Так, давайте по подробнее.  
У нас есть 2 типа поля (предположим)  
1 - text  
2 - keyword

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

Я думал что мы можем делать поиск regexp только по 2 типу. В таком случае мы ищем по всему полю целиком.  
А что будет если мы будем искать по 1 типу с использованием regexp?  
Правильно ли я понимаю, что если мы проиндексируем 2 текста  
1 - "Нефтяные вышки"  
2 - "Производство нефти"  
то мы получим следующие ключевые слова для предложений  
1 - нефтяной, вышка  
2 - производство, нефть

Если мы используем match поиск по слову "нефть" то мы найдём только 2-е предложение  
Если match по слову "нефтяной" то только 1-е предложение  
А если мы будем использовать regexp поиск по text типу по слову `".*нефт.*"` то найдём оба предложения и поиск при этом будет производится именно по ключевым словам?

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [November 4, 2017, 2:30pm UTC](https://discuss.elastic.co/t/topic/103999/6 "2017-11-04T14:30:20Z")

</div>

`regex` в любом случае ищет по токенам, только в первом случае, токены эти генерируются анализатором и состоят из слов, а во втором случае - токен у вас один - вся строка.

---

<div class="post-metadata">

### Author: ![FilimonovAP](https://avatars.discourse-cdn.com/v4/letter/f/e36b37/32.png) [@FilimonovAP](https://discuss.elastic.co/u/FilimonovAP)
#### Post date: [November 4, 2017, 2:56pm UTC](https://discuss.elastic.co/t/topic/103999/7 "2017-11-04T14:56:32Z")

</div>

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

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

Я правильно понимаю что тогда мне для поиска "мама мыла раму" по частям двух слов "`ма.*`" и "`ра.*`" придётся разбивать запрос на два regexp query связанных must?  
Если бы я использовал match то достаточно было бы одного query как "мама раму". Такой фокус с regexp не пройдёт?

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [November 4, 2017, 7:25pm UTC](https://discuss.elastic.co/t/topic/103999/8 "2017-11-04T19:25:59Z")

</div>

> [@FilimonovAP](#):
>
> Я правильно понимаю что тогда мне для поиска "мама мыла раму" по частям двух слов "ма._" и "ра._" придётся разбивать запрос на два regexp query связанных must?

да, один запрос `regex` ищет только по одному токену

> [@FilimonovAP](#):
>
> Если бы я использовал match то достаточно было бы одного query как "мама раму". Такой фокус с regexp не пройдёт?

Это потому, что `match` автоматически разбивает ваш запрос на два запроса.

---

<div class="post-metadata">

### Author: ![FilimonovAP](https://avatars.discourse-cdn.com/v4/letter/f/e36b37/32.png) [@FilimonovAP](https://discuss.elastic.co/u/FilimonovAP)
#### Post date: [November 4, 2017, 7:29pm UTC](https://discuss.elastic.co/t/topic/103999/9 "2017-11-04T19:29:33Z")

</div>

Спасибо огромное за пояснения.  
Теперь всё встало на свои места.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [December 2, 2017, 7:29pm UTC](https://discuss.elastic.co/t/topic/103999/10 "2017-12-02T19:29:56Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
