Elasticsearch: выигрыш с помощью Ngrams
У меня прямой вопрос, где я включил Ngram для частичных совпадений. Реализация работает хорошо, но результаты оценки не работают, как я надеялся. Я бы хотел, чтобы результаты моих оценок выглядели примерно так:
- Ke:.1
- Кев: .2
- Кеви: .3
- Кевин:.4
Вместо этого я получаю следующие результаты, где оценка одинакова, если есть совпадение для поля:
- Ke:.4
- Кев:.4
- Кеви:.4
- Кевин:.4
Настройки:
settings: {
analysis: {
filter: {
ngram_filter: {
type: 'edge_ngram',
min_gram: 2,
max_gram: 15
}
},
analyzer: {
ngram_analyzer: {
type: 'custom',
tokenizer: 'standard',
filter: [
'lowercase',
'ngram_filter'
]
}
}
}
}
Отображения:
mappings: [{
name: 'voter',
_all: {
'type': 'string',
'analyzer': 'ngram_analyzer',
'search_analyzer': 'standard'
},
properties: {
last: {
type: 'string',
required : true,
include_in_all: true,
analyzer: 'ngram_analyzer',
search_analyzer: 'standard'
},
first: {
type: 'string',
required : true,
include_in_all: true,
analyzer: 'ngram_analyzer',
search_analyzer: 'standard'
},
}
}]
Запрос:
GET /user/_search
{
"query": {
"match": {
"_all": {
"query": "Ke",
"operator": "and"
}
}
}
}
1 ответ
Вы можете решить это, используя edgeNGram
токенизатор вместо edgeNGram
фильтр:
settings: {
analysis: {
tokenizer: {
ngram_tokenizer: {
type: 'edge_ngram',
min_gram: 2,
max_gram: 15
}
},
analyzer: {
ngram_analyzer: {
type: 'custom',
tokenizer: 'ngram_tokenizer',
filter: [
'lowercase'
]
}
}
}
}
Причина этого заключается в том, что edgeNGram
фильтр запишет термины для данного токена в той же позиции (почти как синонимы), в то время как edgeNGram
tokenizer создаст токены, которые имеют разные позиции, что влияет на нормализацию длины и, следовательно, на оценку.
Обратите внимание, что это работает только в выпусках ES до версии 2.0, потому что составная оценка вычисляется из всех оценок токенов ngram, тогда как в ES 2.x оценивается только соответствующий токен.