Проблема
Я работаю над автозаполнением, используя ElasticSearch 6.2.3. Я бы хотел, чтобы результаты моего запроса (список страниц с полем «Имя») были упорядочены с использованием следующего приоритета:
- Соответствие префикса в начале «Имени» (запрос префикса)
- Любое другое точное (целое слово) совпадение в пределах «Имя» (термин запроса)
- Нечеткое совпадение (в настоящее время это делается в поле, отличном от имени, с помощью токенайзера ngram ... поэтому я предполагаю, что это не может относиться к моей проблеме, но я также хотел бы применить это к полю имени)
Моя попытка решения
Я буду использовать запрос Bool / If, состоящий из трех запросов (соответствующих трем приоритетам выше), используя boost для определения относительной важности.
Проблема, с которой я столкнулся, связана с запросом префикса - он, похоже, не вмещает поисковый запрос в нижнем регистре, несмотря на то, что в моем поисковом анализаторе установлен фильтр нижнего регистра . Например, приведенный ниже запрос возвращает «Гарри Поттер» для «Гарри», но возвращает ноль результатов для «Гарри»:
{ "query": { "prefix": { "Name.raw" : "Harry" } } }
Я с помощью API _analyze
подтвердил, что оба моих анализатора действительно переводят текст с «Гарри» на «Гарри». Куда я иду не так?
Из документации ES я понимаю, что нужно проанализировать поле Имя двумя различными способами, чтобы разрешить использование запросов префикса и термина:
с помощью токенайзера "keyword" для включения запроса Prefix (я применил это к полю .raw
)
с использованием стандартного анализатора для включения Term (я применил это в поле Имя)
Я проверил дубликаты вопросов, таких как этот , но ответы не помогли
Мое сопоставление и настройки ниже
Отображение индекса ES
{
"myIndex": {
"mappings": {
"pages": {
"properties": {
"Id": {},
"Name": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keywordAnalyzer",
"search_analyzer": "pageSearchAnalyzer"
}
},
"analyzer": "pageSearchAnalyzer"
},
"Tokens": {}, // Other fields not important for this question
}
}
}
}
}
Настройки индекса ES
{
"myIndex": {
"settings": {
"index": {
"analysis": {
"filter": {
"ngram": {
"type": "edgeNGram",
"min_gram": "2",
"max_gram": "15"
}
},
"analyzer": {
"keywordAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding"
],
"type": "custom",
"tokenizer": "keyword"
},
"pageSearchAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding"
],
"type": "custom",
"tokenizer": "standard"
},
"pageIndexAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding",
"ngram"
],
"type": "custom",
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"uuid": "l2AXoENGRqafm42OSWWTAg",
"version": {}
}
}
}
}