【发布时间】:2015-07-02 00:55:08
【问题描述】:
我刚刚开始使用 ElasticSearch 并尝试基于它实现自动完成功能。
我有一个autocomplete 索引,其中包含city 类型为string 的字段。以下是存储在此索引中的文档示例:
{
"_index":"autocomplete_1435797593949",
"_type":"listing",
"_id":"40716",
"_source":{
"city":"Rome",
"tags":[
"listings"
]
}
}
分析配置如下所示:
{
"analyzer":{
"autocomplete_term":{
"tokenizer":"autocomplete_edge",
"filter":[
"lowercase"
]
},
"autocomplete_search":{
"tokenizer":"keyword",
"filter":[
"lowercase"
]
}
},
"tokenizer":{
"autocomplete_edge":{
"type":"nGram",
"min_gram":1,
"max_gram":100
}
}
}
映射:
{
"autocomplete_1435795884170":{
"mappings":{
"listing":{
"properties":{
"city":{
"type":"string",
"analyzer":"autocomplete_term"
},
}
}
}
}
}
我正在向 ES 发送以下查询:
{
"query":{
"multi_match":{
"query":"Rio",
"analyzer":"autocomplete_search",
"fields":[
"city"
]
}
}
}
结果,我得到以下信息:
{
"took":2,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"failed":0
},
"hits":{
"total":1,
"max_score":2.7742395,
"hits":[
{
"_index":"autocomplete_1435795884170",
"_type":"listing",
"_id":"53581",
"_score":2.7742395,
"_source":{
"city":"Rio",
"tags":[
"listings"
]
}
}
]
}
}
在大多数情况下,它是有效的。它确实在用户必须实际输入整个单词之前找到带有city = "Rio" 的文档("Ri" 就足够了)。
这就是我的问题。我也希望它返回"Rio de Janeiro"。要获得"Rio de Janeiro",我需要发送以下查询:
{
"query":{
"multi_match":{
"query":"Rio d",
"analyzer":"standard",
"fields":[
"city"
]
}
}
}
注意那里的"<whitespace>d"。
另一个相关问题是,我希望至少所有以"R" 开头的城市都会返回以下查询:
{
"query":{
"multi_match":{
"query":"R",
"analyzer":"standard",
"fields":[
"city"
]
}
}
}
我希望"Rome" 等...(这是一个存在于索引中的文档),但是,我又只得到"Rio"。我希望它的行为类似于SQL LIKE 条件,即... LIKE 'CityName%'。
我做错了什么?
【问题讨论】: