希望长大对我而言,是可以做更多想做的事,而不是被迫做更多不想做的事...... 首页 Elasticsearch之索引管理、自定义分析器、地理坐标点 丁D 学无止境 2019-09-04 10:42 45819已阅读 分析器 索引管理 地理坐标点 摘要本文将讲解索引管理、自定义分析器、地理坐标点。 >**学习目标** 索引管理 自定义分析器 地理坐标点 ##索引管理 [Elasticsearch权威指南-索引管理](https://es.xiaoleilu.com/070_Index_Mgmt/00_Intro.html) 我们之前的index都是在创建document,让es自动帮我们创建index。现在我们来讲解如何手动创建index,以便更好适用我们的应用。 ###创建索引 ```js 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 } ``` ###自定义分析器 ```js 我们知道分析器是由,字符过滤器,分词器,标记过滤器组成 例子: 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 **标记过滤 ###日期检测 ```js 当 Elasticsearch 遇到一个新的字符串字段时,它会检测这个字段是否包含一个可识别的日 期, 比如 2014-01-01 。如果它看起来像一个日期,这个字段会被作为 date 类型添加, 否 则,它会被作为 string 类型添加。 但是实际上这个字段不是一个date类型,只是第一次见到这个字段的值是“2018-05-06” 但是可能第二次这个字段的值就变成了“aaaaaaa”,这显然不是一个日期,但为时已晚。 这个字段已经被添加为日期类型,这个 不合法的日期 将 引发异常。所以要禁止日期检测 PUT /my_index { "mappings": { "my_type": { "date_detection": false } } } ``` **地理坐标点** [Elasticsearch 入门教程 – GEO位置搜索](http://www.dczou.com/viemall/740.html) [Elasticsearch权威指南](https://es.xiaoleilu.com/340_Geoshapes/00_Intro.html) ```js 地理坐标点是指用经纬度来表示地球表面的某一个位置。 可以用来计算两个地方的位置,可以用来判断是不是落在某个区域。 地理坐标点不能被动态映射(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 } ``` **地理坐标盒模型过滤器** ```js 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 } } } } } } } ``` **地理位置距离过滤器** ```js 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%。 ``` ** 地理距离区间过滤器** ```js 地理距离过滤器 ( geo_distance )和 地理距离区间过滤器(geo_distance_range )的唯一差别在 于后者是一个环状的,它会排除掉落在内圈中的那部分文档 5.x已经不支持 [geo_distance_range] queries are no longer supported for geo_point field types. Use geo_distance sort or aggregations ``` 很赞哦! (2) 上一篇:Elasticsearch之持久化、路由过程、CRUD原理、scroll技术 下一篇:ELK搭建和tomcat日志分析 目录 点击排行 Elasticsearch6.3.2之x-pack redis哨兵 2019-07-09 22:05 Redis+Twemproxy+HAProxy+Keepalived 2019-07-12 17:20 GC优化策略和相关实践案例 2019-10-10 10:54 JVM垃圾回收器 2019-10-10 10:23 标签云 Java Spring MVC Mybatis Ansible Elasticsearch Redis Hive Docker Kubernetes RocketMQ Jenkins Nginx 友情链接 郑晓博客 佛布朗斯基 凉风有信 MarkHoo's Blog 冰洛博客 南实博客 Rui | 丁D Java研发工程师 生活可以用「没办法」三个字概括。但别人的没办法是「腿长,没办法」、「长得好看,没办法」、「有才华,没办法」。而你的没办法,是真的没办法。 请作者喝咖啡