我有以下提供的位置信息地名网 http://www.geonames.org/解析成关系数据库。使用这些信息,我尝试构建一个 ElasticSearch 索引,其中包含人口稠密的地名(城市)名称、行政区划(州、省等)名称、国家/地区名称和国家/地区代码。我的目标是提供类似于 Google 地图的位置搜索:
我不需要很酷的粗体突出显示,但我确实需要搜索以类似的方式返回类似的结果。我尝试使用由整个位置名称组成的单个位置字段(例如“美国德克萨斯州朗德罗克”)创建映射,并且我还尝试使用由位置的每个部分组成的五个单独的字段。我尝试过关键字和前缀查询以及edgengram分析器;我一直未能找到正确的配置来使其正常工作。
我应该使用哪些类型的分析器(索引和搜索)来实现我的目标?这个搜索不必像谷歌那样完美,但我希望它至少是相似的。
我确实想支持部分名称匹配,这就是为什么我一直在摆弄edgengram。例如,搜索“round r”应匹配 Round Rock, TX, United States。另外,我希望填充的地名(城市)名称以确切的搜索词开头的结果的排名高于其他结果。例如,搜索“round ro”应先匹配 Round Rock, TX, United States,然后再匹配 Round, Some Province, RO(罗马尼亚)。我希望我已经说得足够清楚了。
这是我当前的索引配置(这是 C# 中的匿名类型,稍后序列化为 JSON 并传递给 ElasticSearch API):
settings = new
{
index = new
{
number_of_shards = 1,
number_of_replicas = 0,
refresh_interval = -1,
analysis = new
{
analyzer = new
{
edgengram_index_analyzer = new
{
type = "custom",
tokenizer = "index_tokenizer",
filter = new[] { "lowercase", "asciifolding" },
char_filter = new[] { "no_commas_char_filter" },
stopwords = new object[0]
},
search_analyzer = new
{
type = "custom",
tokenizer = "standard",
filter = new[] { "lowercase", "asciifolding" },
char_filter = new[] { "no_commas_char_filter" },
stopwords = new object[0]
}
},
tokenizer = new
{
index_tokenizer = new
{
type = "edgeNGram",
min_gram = 1,
max_gram = 100
}
},
char_filter = new
{
no_commas_char_filter = new
{
type = "mapping",
mappings = new[] { ",=>" }
}
}
}
}
},
mappings = new
{
location = new
{
_all = new { enabled = false },
properties = new
{
populatedPlace = new { index_analyzer = "edgengram_index_analyzer", type = "string" },
administrativeDivision = new { index_analyzer = "edgengram_index_analyzer", type = "string" },
administrativeDivisionAbbreviation = new { index_analyzer = "edgengram_index_analyzer", type = "string" },
country = new { index_analyzer = "edgengram_index_analyzer", type = "string" },
countryCode = new { index_analyzer = "edgengram_index_analyzer", type = "string" },
population = new { type = "long" }
}
}
}