Elasticsearch之索引管理、自定义分析器、地理坐标点

2022-08-12 20:47:19 浏览数 (1)

学习目标 索引管理 自定义分析器 地理坐标点

索引管理

Elasticsearch权威指南-索引管理 我们之前的index都是在创建document,让es自动帮我们创建index。现在我们来讲解如何手动创建index,以便更好适用我们的应用。

创建索引

代码语言:javascript复制
put /my_index 
{ 
"settings":{...any setting...}, 
"mappings":{ 
"type_one":{...any mappings...}, 
"type_one":{...any mappings...}, 
.... 
} 
} 
可以在config/elasticsearch.yml添加配置,设置静止自动创建index 
action.auto_create_index:false 
index有3个最重要的配置:设置主分片,设置复制分片,设置分析器 
PUT /my_temp_index { "settings": { "number_of_shards" : 1, "number_of_replicas" : 0 } } 
动态设置副本分片,主分片不能动态修改 
PUT /my_temp_index/_settings { "number_of_replicas": 1 } 

自定义分析器

代码语言:javascript复制
我们知道分析器是由,字符过滤器,分词器,标记过滤器组成 
例子: 
1. 用 html_strip 字符过滤器去除所有的 HTML 标签 
2. 将 & 替换成 and ,使用一个自定义的 mapping 字符过滤器 
"char_filter": { 
"&_to_and": { 
"type": "mapping", 
"mappings": ["&=> and "] 
} 
} 
1. 使用 standard 分词器分割单词 
2. 使用 lowercase 标记过滤器将词转为小写 
3. 用 stop 标记过滤器去除一些自定义停用词。 
"filter": { 
"my_stopwords": { 
"type": "stop", 
"stopwords": ["the", "a"] 
} 
} 
根据以上描述来将预定义好的分词器和过滤器组合成我们的分析器: 
"analyzer": { 
"my_analyzer": { 
"type": "custom", 
"char_filter": ["html_strip", "&_to_and"], 
"tokenizer": "standard", 
"filter": ["lowercase", "my_stopwords"] 
} 
} 
一句话合并请求: 
PUT /my_index 
{ 
"settings": { 
"analysis": { 
"char_filter": { 
"&_to_and": { 
"type": "mapping", 
"mappings": ["&=> and "] 
} 
}, 
"filter": { 
"my_stopwords": { 
"type": "stop", 
"stopwords": ["the", "a"] 
} 
}, 
"analyzer": { 
"my_analyzer": { 
"type": "custom", 
"char_filter": ["html_strip", "&_to_and"], 
"tokenizer": "standard", 
"filter": ["lowercase", "my_stopwords"] 
} 
} 
} 
} 
} 

字符过滤器是让字符串在被分词前变得更加“整洁”。例如 我们可以使用 html_strip 字符过滤器 来删除所有的 HTML 标签 一个分析器 必须 包含一个分词器。分词器将字符串分割成单独的词(terms)或标记 (tokens)。 standard 分析器使用 standard 分词器将字符串分割成单独的字词,删除 大部分标点符号, keyword 分词器输出和它接收到的相同的字符串,不做任何分词处理。 whitespace 分词器只通过空格来分割文本 标记过滤器可能修改,添加或删除标记。我们已经提过 lowercase stop 标记过滤

日期检测

代码语言:javascript复制
当 Elasticsearch 遇到一个新的字符串字段时,它会检测这个字段是否包含一个可识别的日 期, 
比如 2014-01-01 。如果它看起来像一个日期,这个字段会被作为 date 类型添加, 
否 则,它会被作为 string 类型添加。 
但是实际上这个字段不是一个date类型,只是第一次见到这个字段的值是“2018-05-06” 
但是可能第二次这个字段的值就变成了“aaaaaaa”,这显然不是一个日期,但为时已晚。 
这个字段已经被添加为日期类型,这个 不合法的日期 将 引发异常。所以要禁止日期检测 
PUT /my_index 
{ 
"mappings": { 
"my_type": { 
"date_detection": false 
} 
} 
} 

地理坐标点 Elasticsearch 入门教程 – GEO位置搜索 Elasticsearch权威指南

代码语言:javascript复制
地理坐标点是指用经纬度来表示地球表面的某一个位置。 
可以用来计算两个地方的位置,可以用来判断是不是落在某个区域。 
地理坐标点不能被动态映射(dynamic mapping)自动检测, 
而是需要显式声明对应字段类型 为 geo_point 
PUT /address 
{ 
"mappings": { 
"address":{ 
"properties": { 
"name":{ 
"type": "text" 
}, 
"location":{ 
"type": "geo_point" 
} 
} 
} 
} 
} 
PUT /address/address/3 
{ 
"name": "zuipin", 
"location": [118.18191647528275,24.486064774155608] 
} 
表示经纬度有3种表达方式 
(1)以半角逗号分割的字符串形式 "lat,lon" 
"location": "40.715, -74.011" 
(2)数组形式表示 [lon,lat] 
(3)明确以 lat 和 lon 作为属性的对象 
"location": {"lat": 40.722, "lon": -73.989 } 

地理坐标盒模型过滤器

代码语言:javascript复制
geo_bounding_box 
指定一个一个矩形,过滤掉不落在矩形里面的坐标点。 
GET /address/address/_search 
{ 
"query": { 
"bool": { 
"filter": { 
"geo_bounding_box": { 
"location": { 
"top_left": { 
"lat": 40.8, 
"lon": -74.0 
}, 
"bottom_right": { 
"lat": 40.7, 
"lon": -73.0 
} 
} 
} 
} 
} 
} 
} 
优化盒模型 
盒模型我们可以建倒排索引来优化。 
创建index时候就要指定<1> 
"location": { "type": "geo_point", "lat_lon": true <1> } 
在查询的时候<1> 
GET /address/address/_search 
{ 
"query": { 
"bool": { 
"filter": { 
"type": "indexed", <1> 
"geo_bounding_box": { 
"location": { 
"top_left": { 
"lat": 40.8, 
"lon": -74.0 
}, 
"bottom_right": { 
"lat": 40.7, 
"lon": -73.0 
} 
} 
} 
} 
} 
} 
} 

地理位置距离过滤器

代码语言:javascript复制
geo_distance 
地理距离过滤器 ( geo_distance )以给定位置为圆心画一个圆,来找出那些位置落在其中的文档 
GET /address/address/_search 
{ 
"query": { 
"bool": { 
"filter": { 
"geo_distance": { 
"distance": "300m", 
"distance_type": "arc", 
"location": [118.17985653878976,24.4863137535666] 
} 
} 
} 
} 
} 
地理位置距离过滤器代价贵,es先通过构建一个边长为2倍距离的矩形,来围住圆形,过滤掉大部分不在矩形内的坐标点。 
// 
distance_type:arc、plane、sloppy_arc 
arc:把地球当做球体来计算,精准度最好,但是性能较差 
plane:地球当成是平坦的来计算,精准度较差,但是性能较好,赤道比较精准,往两级越来越不准, 
用户真的会在意一个宾馆落在指定圆形区域数米之外了吗?? 
大部分实际应用场景中,使用精度较低但响应更快的 计算方式可能就挺好 
sloppy_arc:是默认的方式,比arc快4~5倍,距离精度达99.9%。 

地理距离区间过滤器

代码语言:javascript复制
地理距离过滤器 ( geo_distance )和 地理距离区间过滤器(geo_distance_range )的唯一差别在 
于后者是一个环状的,它会排除掉落在内圈中的那部分文档 
5.x已经不支持 
[geo_distance_range] queries are no longer supported for geo_ 

0 人点赞