我正在尝试使用ElasticSearch实现地址自动填充。
假设我有三个字段,我想在其中实现搜索:
{
"address_name": "George st.",
"number": "1",
"city_name": "London"
}
根据this article,我已经配置了我的索引并输入如下:
{
"settings": {
"analysis": {
"filter": {
"nGram_filter": {
"type": "nGram",
"min_gram": 1,
"max_gram": 20,
"token_chars": [
"letter",
"digit",
"punctuation",
"symbol"
]
}
},
"analyzer": {
"nGram_analyzer": {
"type": "custom",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"asciifolding",
"nGram_filter"
]
},
"whitespace_analyzer": {
"type": "custom",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"address": {
"_all": {
"analyzer": "nGram_analyzer",
"search_analyzer": "whitespace_analyzer"
},
"properties": {
"address_name": {
"type": "string"
},
"number": {
"type": "string",
"boost": 2
},
"city_name": {
"type": "string"
},
"local": {
"type": "integer",
"include_in_all": false,
"index": "no"
},
"place_id": {
"type": "integer",
"include_in_all": false,
"index": "no"
},
"has_number": {
"type": "integer",
"include_in_all": false,
"index": "no"
}
}
}
}
}
完整搜索查询:
{
"size": 100,
"query": {
"match": {
"_all": {
"query": "George st. 1 London",
"operator": "and"
}
}
}
}
当我按查询George st. 1 London
搜索时,ElasticSearch首先返回George st. 19 London
,George st. 17 London
等,但完全匹配George st. 1 London
仅在第X位返回得分低于第一名。
我试图通过在搜索网址的末尾添加explain
查询来了解其原因,但它没有帮助。
有什么方法可以解决这个问题吗?
谢谢。
答案 0 :(得分:1)
基本上,由于您在索引时通过nGram令牌过滤器运行所有字段,这意味着对于number
字段,
17
将被标记为1
和17
以及19
将被标记为1
和19
因此,您提及的所有三个文档都会为其1
字段编制索引标记number
。
然后在查询时,您正在使用空白分析器,这意味着George st. 1 London
将被标记为以下令牌:George
,st
,{{1} }和1
。
从那里,我们可以得出两个结论:
London
给予更多权重而不是其他文档。最简单的方法是不将nGram应用于数字字段,以便街道号码需要精确匹配,而不是前缀。