地理坐标点数据类型
地理坐标点
地理坐标点是指地球表面可以用经纬度描述的一个点。 地理坐标点可以用来计算两个坐标间的距离,还可以判断一个坐标是否在一个区域中。地理坐标点需要显式声明对应字段类型为 geo_point :
PUT /company-locations
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"location": {
"type": "geo_point"
}
}
}
}
- 经纬度坐标格式
如上例, location 字段被声明为 geo_point 后,我们就可以索引包含了经纬度信息的文档了。 经纬度信息的形式可以是字符串、数组或者对象
PUT /company-locations/_doc/1
{
"name": "NetEase",
"location": "40.715,74.011"
}
PUT /company-locations/_doc/2
{
"name": "Sina",
"location": {
"lat": 40.722,
"lon": 73.989
}
}
PUT /company-locations/_doc/3
{
"name": "Baidu",
"location": [
73.983,
40.719
]
}
字符串形式以半角逗号分割,如 “lat,lon”
对象形式显式命名为 lat 和 lon
数组形式表示为 [lon,lat]
通过地理坐标点过滤
有四种地理坐标点相关的过滤器 可以用来选中或者排除文档
https://www.elastic.co/guide/cn/elasticsearch/guide/current/geo-shapes.html
- 测试
GET /company-locations/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 40.73,
"lon": 71.12
},
"bottom_right": {
"lat": 40.717,
"lon": -73.99
}
}
}
}
}
}
}
GET /company-locations/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": "200km",
"location": {
"lat": 40,
"lon": 70
}
}
}
}
}
}
动态映射
Elasticsearch在遇到文档中以前未遇到的字段,可以使用dynamic mapping(动态映射机制) 来确定
字段的数据类型并自动把新的字段添加到类型映射。
Elastic的动态映射机制可以进行开关控制,通过设置mappings的dynamic属性,dynamic有如下设置
项
true:遇到陌生字段就执行dynamic mapping处理机制
false:遇到陌生字段就忽略
strict:遇到陌生字段就报错
PUT /user
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"dynamic": "strict",
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "object",
"dynamic": true
}
}
}
}
插入以下文档,将会报错
user索引层设置dynamic是strict,在user层内设置age将报错
在address层设置dynamic是ture,将动态映射生成字段
PUT /user/_doc/1
{
"name": "lisi",
"age": "20",
"address": {
"province": "beijing",
"city": "beijing"
}
}
- 删除
DELETE /user
PUT /user
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"dynamic": true,
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "object",
"dynamic": true
}
}
}
PUT /user/_doc/1
{
"name": "lisi",
"age": "20",
"address": {
"province": "beijing",
"city": "beijing"
}
}
自定义动态映射
如果你想在运行时增加新的字段,你可能会启用动态映射。 然而,有时候,动态映射 规则 可能不太智能。幸运的是,我们可以通过设置去自定义这些规则,以便更好的适用于你的数据
日期检测
当 Elasticsearch 遇到一个新的字符串字段时,它会检测这个字段是否包含一个可识别的日期,比如2014-01-01 如果它像日期,这个字段就会被作为 date 类型添加。否则,它会被作为 string 类型添加。
有些时候这个行为可能导致一些问题。想象下,你有如下这样的一个文档:
{ “note”: “2014-01-01” }
假设这是第一次识别 note 字段,它会被添加为 date 字段。但是如果下一个文档像这样:
{ “note”: “Logged out” }
这显然不是一个日期,但为时已晚。这个字段已经是一个日期类型,这个 不合法的日期 将会造成一个异常。
日期检测可以通过在根对象上设置 date_detection 为 false 来关闭
PUT /my_index/_doc/1
{
"note": "2014-01-01"
}
get /my_index/_mapping
{
“my_index” : {
“mappings” : {
“properties” : {
“note” : {
“type” : “date”
}
}
}
}
}
- 错误
PUT /my_index/_doc/2
{
"note": "logout"
}
- 关闭日期检测
DELETE /my_index
PUT /my_index
{
"mappings": {
"date_detection": false
}
}
使用这个映射,字符串将始终作为 string 类型。如果需要一个 date 字段,必须手动添加。Elasticsearch 判断字符串为日期的规则可以通过 dynamic_date_formats setting 来设置
DELETE /my_index
PUT /my_index
{
"mappings": {
"dynamic_date_formats": "yyyy-MM-dd"
}
}
PUT /my_index/_doc/1
{
"note": "2014-01-01"
}
PUT /my_index/_doc/1
{
"note": "01/01/2014"
}
get /my_index/_mapping
ynamic_templates
使用 dynamic_templates 可以完全控制新生成字段的映射,甚至可以通过字段名称或数据类型来应用不同的映射。每个模板都有一个名称,你可以用来描述这个模板的用途,一个 mapping 来指定映射应该怎样使用,以及至少一个参数 (如 match) 来定义这个模板适用于哪个字段。
模板按照顺序来检测;第一个匹配的模板会被启用。例如,我们给 string 类型字段定义两个模板:
es :以 _es 结尾的字段名需要使用 spanish 分词器。
en :所有其他字段使用 english 分词器。
我们将 es 模板放在第一位,因为它比匹配所有字符串字段的 en 模板更特殊
1)匹配字段名以 _es 结尾的字段
2)匹配其他所有字符串类型字段
match_mapping_type 允许你应用模板到特定类型的字段上,就像有标准动态映射规则检测的一样 (例
如 string 或 long)
match参数只匹配字段名称,path_match 参数匹配字段在对象上的完整路径,所以 address.*.name
将匹配这样的字段
PUT /my_index2
{
"mappings": {
"dynamic_templates": [
{
"es": {
"match": "*_es",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"analyzer": "spanish"
}
}
},
{
"en": {
"match": "*",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"analyzer": "english"
}
}
}
]
}
}
PUT /my_index2/_doc/1
{
"name_es":"testes",
"name":"es"
}
{
“address”: {
“city”: {
“name”: “New York”
}
}
}