Как объяснено в моем комментарии выше, следует избегать подстановочных знаков префиксов любой ценой по мере роста индекса, поскольку это заставит ES выполнять полное сканирование индекса.Я до сих пор убежден, что ngrams (точнее, edge-ngrams) - это путь, поэтому я делаю удар ниже:
Идея состоит в том, чтобы проиндексировать все суффиксы ввода, а затемиспользуйте prefix
запрос для сопоставления с любым суффиксом, поскольку при поиске префиксов не возникают те же проблемы с производительностью, что и при поиске суффиксов.Таким образом, идея состоит в том, чтобы индексировать john doe
следующим образом:
john doe
ohn doe
hn doe
n doe
doe
oe
e
Таким образом, используя запрос prefix
, мы можем сопоставить любую часть этих токенов, которая эффективно достигает цели сопоставления частично смежных словв то же время обеспечивая хорошую производительность.
Определение индекса будет выглядеть следующим образом:
PUT my_index
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"reverse",
"suffixes",
"reverse"
]
}
},
"filter": {
"suffixes": {
"type": "edgeNGram",
"min_gram": 1,
"max_gram": 20
}
}
}
}
},
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text",
"analyzer": "my_analyzer",
"search_analyzer": "standard"
}
}
}
}
}
Тогда мы можем проиндексировать образец документа:
PUT my_index/doc/1
{
"name": "john doe"
}
* 1018И, наконец, все последующие поиски вернут документ
john doe
:
POST my_index/_search
{
"query": {
"prefix": {
"name": "john doe"
}
}
}
POST my_index/_search
{
"query": {
"prefix": {
"name": "john do"
}
}
}
POST my_index/_search
{
"query": {
"prefix": {
"name": "ohn do"
}
}
}
POST my_index/_search
{
"query": {
"prefix": {
"name": "john"
}
}
}
POST my_index/_search
{
"query": {
"prefix": {
"name": "n doe"
}
}
}