问题描述
如何在Elasticsearch中存储国家/州/城市信息
i.e there are many countries
each country has many states
each state has many cities
存储在关系数据库中更容易,但是如果我想存储所有可能的组合,该如何在Elasticsearch中进行
我想将国家,州,城市位置存储在包含用户信息的某个索引中
i.e users (first_name,last_name,country,state,city ...)
解决方法
请不要将Elasticsearch与RDBMS混淆,并且您没有提到用例是什么,即全文搜索或聚合,我将向您展示如何使用数据及其简单的方法实现全文搜索不需要太多的配置/复杂性即可实现。
由于一次只能将一个用户留在一个城市,州和国家/地区,但是如果您想为用户存储多个选项(也可以这样做),则只需索引分隔的,
值。
如果您需要在这些字段上进行汇总,请将这些字段索引为keyword
,以便可以对其进行汇总。
完整的全文搜索示例
索引映射
{
"mappings" :{
"properties" :{
"first_name" :{
"type" : "text"
},"last_name" :{
"type" : "text"
},"country" :{
"type" : "text"
},"state" :{
"type" : "text"
},"city" :{
"type" : "text"
}
}
}
}
索引样本文档
{
"first_name" : "abc","last_name" : "xyz","country": "USA","state" : "California","city" : "SF"
}
{
"first_name" : "opster","last_name" : "ninja","country": "Israel","state" : "na","city" : "tel aviv"
}
{
"first_name" : "abc","state" : "California,washintion",// not two state
"city" : "SF"
}
现在搜索California
将返回第一和第三文档,如下所示
{
"query": {
"match": {
"state": "california"
}
}
}
和搜索结果
"hits": [
{
"_index": "so_63601020","_type": "_doc","_id": "3","_score": 0.38845783,"_source": {
"first_name": "abc","last_name": "xyz","state": "California","city": "SF"
}
},{
"_index": "so_63601020","_id": "2","_score": 0.2863813,"_source": {
"first_name": "foo","last_name": "bar","state": "California,washington","city": "SF"
}
}
]
,
数据重复是任何NoSQL数据库/服务(包括ElasticSearch)的折衷方案。这里的主要思想是,您不需要具有所有可能的城市/州/国家/地区组合的单独索引。
话虽如此,每个用户可能只会居住在一个城市。另外,一个人的城市/州/国家经常会发生变化是极不可能的。完成后,您只需更新该用户的文档即可。因此,频繁的更新(NoSQL的重要缺点)在这里不会引起太大的关注。
我的建议是确保您设置fielddata: true
和/或将城市/州/国家/地区字段也设置为keyword
数据类型,以便您可以快速回答诸如“我的大多数用户位于哪个状态?”之类的问题。等,方法是使用aggregations。
重要:请考虑一些标准化/标准化,尤其是。当涉及到城市和州时。如果我们谈论美国:
- 某些人可能会以
Massachusetts
的身份进入他们的州,其他人可能会以Mass.
的身份进入他们的州,大多数人会以MA
的身份进入他们的州。您将如何处理? - 类似地,
NYC
与New York
不同,New York City
与new york city
也不同。
通常要做的是地址自动填充/下拉列表(提供开源和收费服务),可以为您提供大量的标准化,因此您可以将用户信息直接保存在elasticsearch索引中。还有地理编码方面,但这是另一回事。