Доброго времени суток!
Настраиваю elasticSearch для поиска по базе мероприятий. Поиск нужен по полному слову и по подстрокам тоже. Настроил анализаторы и маппинг:
{ "template" : "*", "settings" : { "analysis" : { "analyzer" : { "russian_indexer" : { "type" : "custom", "tokenizer" : "rus_nGram", "filter" : [ "russian_morphology", "rus_snow", "rus_stop", "rus_delim", "lowercase" ] }, "russian_searcher" : { "type" : "custom", "tokenizer" : "letter", "filter" : [ "russian_morphology", "rus_snow", "rus_stop", "rus_delim", "lowercase" ] } }, "tokenizer" : { "rus_nGram" : { "type": "nGram", "min_gram": 3, "max_gram": 8 } }, "filter" : { "rus_snow" : { "type" : "snowball", "language" : "Russian" }, "rus_stop": { "type": "stop", "language": "_russian_" }, "rus_delim": { "type": "word_delimiter" } } } }, "mappings" : { "_default_" : { "_all" : { "enabled" : false }, "properties" : { "content" : { "type" : "text", "analyzer" : "russian_indexer", "search_analyzer" : "russian_searcher" }, "title" : { "type" : "text", "analyzer" : "russian_indexer", "search_analyzer" : "russian_searcher" }, "full_info" : { "type" : "text", "analyzer" : "russian_indexer", "search_analyzer" : "russian_searcher" }, "short_info" : { "type" : "text", "analyzer" : "russian_indexer", "search_analyzer" : "russian_searcher" }, "role" : { "type" : "text", "analyzer" : "russian_indexer", "search_analyzer" : "russian_searcher" }, "name" : { "type" : "text", "analyzer" : "russian_indexer", indent preformatted text by 4 spaces "search_analyzer" : "russian_searcher" }, "created_at" : { "type": "date" } } } } }
Настроил морфологию и ngram.
Из кода php обращаю к Эластику:
$params = [ 'index' => ['shows'], 'type' => ['show'], 'explain' => true, 'body' => [ 'query' => [ 'function_score' => [ 'query' => [ "dis_max" => [ "queries" => [ [ 'multi_match' => (object)[ 'query' => $searchQuery, 'type' => 'best_fields', 'fields' => ['name^10', 'short_info^5', 'full_info', 'content', 'title^10', 'role^5'], "boost" => 10 ] ], [ 'multi_match' => (object)[ 'query' => $searchQuery, 'fields' => ['name^10', 'short_info^5', 'full_info', 'content', 'title^10', 'role^5'], "analyzer" => "russian_searcher", "boost" => 1 ] ] ], ] ] ], ] ] ];
Но результаты меня не удовлетворяют. Мне нужно, чтобы boost=10 применялся только тогда, когда произошло совпадение по синониму.
Если я правильно понимаю, мне нужно создать один анализатор для ngram, а один - для морфологии. Сейчас, если я хочу найти "Красную шапочку" по запросу "Красный", он находит подстроку "Красн" и дает ей boost=10 но в explain'е пишет, что это подстрока (как nGram).
Надеюсь на помощь, вывод самого эластика могу предоставить