我会这样做:
"tokenizer": {
"autocomplete_edge": {
"type": "edge_nGram",
"min_gram": 1,
"max_gram": 100
}
}
"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"
}
}
}
}
}
}