我会这样做:
- 将令牌生成器更改为
edge_nGram
您曾说过的需要LIKE 'CityName%'
(表示前缀匹配):
"tokenizer": { "autocomplete_edge": { "type": "edge_nGram", "min_gram": 1, "max_gram": 100 } }- 将字段指定
autocomplete_search
为search_analyzer
。我认为拥有keyword
and 是一个不错的选择lowercase
:
"mappings": { "listing": { "properties": { "city": { "type": "string", "index_analyzer": "autocomplete_term", "search_analyzer": "autocomplete_search" } } } }- 查询本身很简单:
{ "query": { "multi_match": { "query": "R", "fields": [ "city" ] } } }详细的解释是这样的:将城市名称分割为ngram。例如,
Rio de Janeiro您将为以下内容编制索引:
"city": [ "r", "ri", "rio", "rio ", "rio d", "rio de", "rio de ", "rio de j", "rio de ja", "rio de jan", "rio de jane", "rio de janei", "rio de janeir", "rio de janeiro" ]
您会注意到所有内容都是小写的。现在,您希望查询采用任何文本(是否为小写),并将其与索引中的内容匹配。因此,
R应该与上面的列表匹配。
为此,您希望输入文本小写并与用户设置的文本保持一致,这意味着不应对其进行分析。你为什么要这个?因为您已经用ngram分割了城市名称,并且不想为输入文本使用相同的名称。如果用户输入“
RI”,Elasticsearch将小写
ri--并将其与索引中的内容完全匹配。
可能更快的替代方法
multi_match是使用
term,但这要求您的应用程序/网站将文本小写。这样做的原因是
term根本不分析输入文本。
{ "query": { "filtered": { "filter": { "term": { "city": { "value": "ri" } } } } } }


