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

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

К сути.
Использую ES 5.4.0
Создал следующую модель:
PUT 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
{ "index": {}}
{ "name" : "электрообогрева"}
{ "index": {}}
{ "name" : "электрообогревом"}
{ "index": {}}
{ "name" : "Резервуарное"}
{ "index": {}}
{ "name" : "обогреватель"}
{ "index": {}}
{ "name" : "стрелецкий"}
{ "index": {}}
{ "name" : "листопад"}
{ "index": {}}
{ "name" : "tt"}

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

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

POST http://localhost:9200/test_search/first_test/_search
{
"query" :{
"match":{
"name" : {
"query" : "обогрев",
"operator" : "and"
}
}
}
}

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

POST http://localhost:9200/test_search/first_test/_search
{
"query" :{
"match":{
"name" : {
"query" : "резервуар",
"operator" : "and"
}
}
}
}

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

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

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

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

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

Тут две проблемы - некачественная лемматизация и составные сложные слова.
russian это очень примитивный анализатор, он с русским языком справиться толком не может, отсюда причуды с лемматизацией. Для русского языка надо использовать что-нибудь помощнее, вроде hunspell или russian_morphology.

Для того, чтобы разбивать составные сложные слова нужен decompounder.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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