Русская морфология

Здравствуйте.
Я использую ES версии 1.7.0 + elasticsearch-analysis-morphology (полагаю, версии 1.2.1).
В настройках я имею:


"analyzer": {
"ru_analyzer": {
"filter": [
"lowercase",
"russian_morphology",
"english_morphology",
"my_stopwords"
],
"type": "custom",
"tokenizer": "standard"
}
}
Мапинг для типа:
"name": {
  "type": "string",
  "store": true,
  "analyzer": "ru_analyzer"
}
Проблема заключается в поиске русских слов по корню с одним или несколькими суффиксами и окончанием. Например, имеем name="Парковые территории". В поисковую строку вводим "парк" и видим пустой результат; вводим "парков" - запись найдена. Standart токенайзер разбирает "Парковые" на "парков", но при этом "Важнейшие" он разберет до "важн". Как можно решить мою проблему?

Я думаю, что этот вопрос лучше всего задать автору русского морфологического анализатора тут - https://github.com/AKuznetsov/russianmorphology

Понимаю, что лучше обратиться к первоисточнику. Но даже если будут исправления на том уровне, то все равно нужно будет их как-то перенести в плагин Эластика. Даже если все получится, то это займет много времени.
Интересует возможность решить проблему каким-то обходным путем, если это возможно. Я лично вижу два варианта: EdgeNGram, но тогда мы будем получать в результатах много лишнего; и второй - пополняемый словарь синонимов для search-анализатора, т.е. ru_analyzer использовать для индекса, а к разобранной строке поиска подмешивать нужные токены из словаря. Второй вариант кажется вполне удачным, если я правильно понял, что в этом случае не придется пересоздавать индексы после пополнения словаря. Поправьте меня, пожалуйста, если я неправ, или может подскажете еще варианты решения.

Вы не могли бы описать более подробнее, что вы подразумеваете под

Проблема заключается в поиске русских слов по корню с одним или несколькими суффиксами и окончанием.

Из двух негативных примеров, которые вы привели, не понятно, какой результат вы ожидаете. Хотелось бы увидеть описание поведения анализатора, которое вы хотите воплотить или хотя бы больше примеров того, как этот анализатор должен работать.

Сейчас я частично реализовал второй вариант. Настройки сейчас такие:
"analyzer": {
"ru_search_analyzer": {
"type": "custom",
"filter": [
"lowercase",
"my_stopwords",
"my_synonyms",
"russian_morphology",
"english_morphology"
],
"tokenizer": "standard"
},
"ru_analyzer": {
"filter": [
"lowercase",
"my_stopwords",
"russian_morphology",
"english_morphology"
],
"type": "custom",
"tokenizer": "standard"
}
}
...
"filter": {
"my_synonyms": {
"type": "synonym",
"synonyms" : ["парк => парков"]
}
Т.е. имеем два анализатора - один для индексации, второй для поиска(search_analyzer в маппинге), в котором слово "парк" заменяется на "парков", а далее фильтром морфологии получаем и парк, и парковый - все работает как задумано. Но я столкнулся с проблемой подключения файла словаря в настройках - "synonyms_path": "synonyms.txt" - не подхватывает файл "synonyms.txt" из папки config. В чем может быть проблема? ОС Windows.

А что он при этом говорит и пишет в логи?

В логах:
"... nested: FailedToResolveConfigException[Failed to resolve config path [synonyms.txt], tried file path [synonyms.txt], path file [C:\elasticsearch\config\synonyms.txt], and classpath];"

И файл C:\elasticsearch\config\synonyms.txt существует и доступен для чтения? Как вы запускаете elasticsearch и какую версию elasticsearch, Windows и Java вы используете?

Да, файл конечно существует и доступен, в нем одна строка - "парк => парков". Elasticsearch версии 1.7.0 запускается автоматически как windows service (c:\elasticsearch\bin\elasticsearch-service-x64.exe //RS//elasticsearch-service-x64) под Windows 7 и Java версии 8.45

Доступен кому? Вам или пользователю, под которым windows service запущен?

Всем полный доступ, чтоб наверняка исключить эту причину.

Странно. К сожалению, у меня нет под рукой машины с Windows 7 что бы попробовать и посмотреть, что там происходит, но судя по описанию похоже на баг. Завтра на Windows 10 попробую воспроизвести. А вы полный путь к файлу задавать не пробовали?

Попробовал такой вариант: "synonyms_path" : "C:\elasticsearch\config\synonyms.txt" - индекс вообще не создается с аналогичной ошибкой.

У вас сколько машин в кластере? Этот файл присутствует на каждой машине?

Как я могу узнать сколько машин в кластере? А лучше сразу бы узнать, как ограничить кластер единственной машиной?

curl "localhost:9200/_cluster/health?pretty"

Не запускать elasticsearch с тем же именем кластера на других машинах. Либо добавить следующее в elastcisearch.yml.

node.max_local_storage_nodes: 1
network.host: "127.0.0.1"
discovery.zen.ping.unicast.hosts: ["127.0.0.1"]
discovery.zen.ping.multicast.enabled: false

Добавил указанные вами настройки в elastcisearch.yml - индекс создался без ошибок, в логах нет упоминаний про synonyms.txt, но синонимы из файла все равно не работают, судя по _analyze.

А можно на вывод следующих команд посмотреть?

curl localhost:9200/ИМЯ_ИНДЕКСА

и

curl localhost:9200/ИМЯ_ИНДЕКСА/_analyze -d '{
 ... ваш тест анализатора ...
}'
{
   "opod": {
      "aliases": {},
      "mappings": {
         "ds1465": {
            "_all": {
               "enabled": true,
               "index_analyzer": "ru_analyzer",
               "search_analyzer": "ru_search_analyzer"
            },
            "properties": {
               "Id": {
                  "type": "string"
               },
               "address": {
                  "type": "string",
                  "store": true,
                  "index_analyzer": "ru_analyzer",
                  "search_analyzer": "ru_search_analyzer",
                  "search_quote_analyzer": "ru_analyzer"
               },
               "caption": {
                  "type": "string",
                  "store": true,
                  "index_analyzer": "ru_analyzer",
                  "search_analyzer": "ru_search_analyzer",
                  "search_quote_analyzer": "ru_analyzer"
               }
            }
         }
      },
      "settings": {
         "index": {
            "creation_date": "1459182850853",
            "analysis": {
               "filter": {
                  "my_synonyms": {
                     "type": "synonym",
                     "synonyms_path" : "synonyms.txt"
                  },
                  "my_stopwords": {
                     "type": "stop",
                     "stopwords": "а,без,более,бы ..."
                  }
               },
               "analyzer": {
                  "ru_search_analyzer": {
                     "type": "custom",
                     "filter": [
                        "lowercase",
                        "my_stopwords",
                        "russian_morphology",
                        "english_morphology",
                        "my_synonyms"
                     ],
                     "tokenizer": "standard"
                  },
                  "ru_analyzer": {
                     "filter": [
                        "lowercase",
                        "my_stopwords",
                        "russian_morphology",
                        "english_morphology"
                     ],
                     "type": "custom",
                     "tokenizer": "standard"
                  }
               }
            },
            "number_of_shards": "1",
            "number_of_replicas": "0",
            "version": {
               "created": "1070099"
            },
            "uuid": "tw5CL8QZSqSdFEEGqv93xg"
         }
      },
      "warmers": {}
   }
}

Результат analyze для анализатора ru_search_analyzer по слову "парк":

{
"tokens": [
{
"token": "парк",
"start_offset": 2,
"end_offset": 6,
"type": <ALPHANUM>,
"position": 1
}
]
}

Если в настройках вместо synonyms_path указать
"synonyms": [ "парк => парк, парковый" ]
то анализатор покажет:
{
"tokens": [
{
"token": "парк",
"start_offset": 2,
"end_offset": 6,
"type": "SYNONYM",
"position": 1
},
{
"token": "парковый",
"start_offset": 2,
"end_offset": 6,
"type": "SYNONYM",
"position": 1
}
]
}

В файле соответственно та же строчка: парк => парк, парковый

Игорь, есть ли какие-то мысли? Возможно, обновление до последней версии поможет?