Запрос на совпадение Elasticsearch с частичным совпадением текста
Вопрос новичка об эластичном поиске. Я настроил индекс luceneasticsearch и использую поиск по именам, содержащим некоторые термины, такие как
search_response = es.search(index = 'sample', body = {'query':{'match':{'first_name':"JUST"}}})
Это не возвращает мне имя "JUSTIN", но следующий запрос
search_response = es.search(index = 'sample', body = {'query':{'match':{'first_name':"JUSTIN"}}})
Что я делаю неправильно? Разве запрос "match" не должен возвращать мне записи, которые содержат термин? Благодарю.
1 ответ
Лучший способ справиться с этой потребностью - создать собственный анализатор, использующий токен-фильтр edgeNGram. Забудьте о подстановочных знаках и использовании *
в строках запроса все они не соответствуют подходу edgeNGram.
Таким образом, вы должны сначала создать свой индекс, а затем переиндексировать данные в него.
curl -XPUT http://localhost:9200/sample -d '{
"settings": {
"analysis": {
"filter": {
"prefixes": {
"type": "edgeNGram",
"min_gram": 1,
"max_gram": 15
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "prefixes"]
}
}
}
},
"mappings": {
"your_type": {
"properties": {
"first_name": {
"type": "string",
"analyzer": "my_analyzer",
"search_analyzer": "standard"
}
}
}
}
}'
Тогда при индексации first_name: JUSTIN
вы получите следующие индексированные токены: j
, ju
, jus
, just
, justi
, justin
В основном все префиксы JUSTIN.
После этого вы сможете выполнить поиск по второму запросу и фактически найти то, что ожидаете.
search_response = es.search(index = 'sample', body = {'query':{'match':{'first_name':'JUST'}}})