elasticsearch(ES)基础学习
心血来潮学习一下es,
哔哩哔哩上找了找课程,综合筛选了一下,选择了黑马的视频
一下是视频过程中,记录的笔记!!!
文章目录
1.采用倒排索引
-
词条(term): 按语义分成的词语
-
文档(document):每条数据就是一个文档
2.es与mysql对比
ES: 面向文档存储的,一条数据就是一个文档。
文档数据会被序列化json格式后存储在elasticsearch中
索引(index):相同类型的文档的集合,如:订单信息(订单索引)、人员信息(人员索引)。
映射(mapping): 索引中文档的约束,类似数据库中的表结构(Schema).
概念对比
架构
- Mysql: 擅长事务类型操作;可以确保数据的安全和一致性。
- Elasticsearch: 擅长海量数据的搜索、分析、计算。
3.安装
3.1.安装 es(部署单点es)
采用的elasticsearch7.12.1版本镜像
-
创建网络
因为需要部署kibana容器,因此需要让es和kibana容器互联;这里先创建一个网络:
docker network create es-net
-
加载镜像
docker load -i es.tar
-
运行
运行docker命令,部署单点es:
3.2.安装 kibana
采用的elasticsearch7.12.1版本镜像.
可以提供可视化界面,方便管理.
-
加载镜像
docker load -i kibana.tar
-
部署
运行docker命令,部署kibana:
3.3.安装IK分词器
es在创建倒排索引时需要对文档进行分词;在搜索时需要对输入内容分词;
默认的分词规则对中文不太友好。在处理中文分词,一般会使用IK分词器
测试:
-
安装ik插件(在线较慢,不推荐)
-
离线安装ik插件(推荐)
1)查看数据卷目录
安装插件需要知道elasticsearch的plugins目录的位置,我们使用了数据卷的挂载,因此需要查看elasticsearch的数据卷目录,
使用命令查看:
docker volume inspect es-plugins
显示结果:
2)解压缩、上传分词器安装包,重命名为ik
解压后,上传到数据卷的目录。
3)重启容器
# 重启容器 docker restart es
# 查看es日志 docker logs -f es
- 测试
ik分词器2中模式:
- ik_smart : 智能切分、最少切分;粗粒度
- ik_max_word : 最细切分;细粒度(耗内存)
3.4.IK分词器的拓展和停用词典
拓展新的词语
停用无意义的词
- 修改ik分词器目录中的config目录中的ikAnalyzer.cfg.xml文件。
- 拓展:在ext.dic的文件中添加想要拓展的词语
- 停用:在stopword.dic的文件中添加想要停用的词语
注意:需要重启es,才能起作用
4.操作索引库(类似数据库中的表)
- mapping映射的属性
- 索引库的CRUD
4.1.mapping映射
mapping是对索引库中文档的约束,常见的mapping属性:
- type: 字段数据类型,常见的类型:
- 字符串:text(可分词的文本)、keyword: (精确值,例如:品牌、国家、ip地址)
- 数值:long、integer、sort、byte、double、float
- 布尔:boolean
- 日期:date
- 对象:object
- index:是否创建索引(倒排索引),默认为true。
- analyzer:使用哪种分词器
- properties:该字段的子字段
4.2.索引库的CRUD
- 创建索引库
ES中通过Restful请求操作索引库、文档。请求内容用哪个DSL语句来表示。
**创建索引库和mapping的DSL语法如下:
**
-
查询、删除索引库
查看:
GET /索引库名称
如:GET /heima
删除:
DELETE /索引库名称
如:DELETE /heima
-
修改索引库
==ES中一般是禁止修改索引库;==但是可以添加新的字段,语法如下:
5.文档的操作(数据的操作)
-
新增文档
DSL语法:
-
查询文档,DSL语法:
-
删除文档,DSL语法:
-
修改文档
-
方式一:全量修改,会删除旧文档,添加新文档
-
方式二:增量修改,修改指定字段值
-
6.RestClient操作索引库
ES提供了各种不同语言的客户端。
这些客户端的本质就是组装DSL语句;
通过http请求发送给ES。
例如:JavaRestClient
通过案例学习
6.1.分析数据结构,编写mapping
-
id:有点特殊,es中一般为
keyword
-
根据业务区分是否分词和参与搜索
-
地理坐标:特殊字段,不是varchar,也不是daouble:
-
(copy_to)解决多个字段搜索,效率又比较高:
6.2. 初始化JavaRestClient(选择RestHighLevelClient)
-
引入es的RestHighLevelClient依赖:
-
覆盖默认的SpringBoot的ES版本:
-
初始化RestHighLevelClient:
6.3.创建索引库
6.4.删除和判断索引库
7.RestClient操作文档
- 创建不同类型的请求对象
- 准备参数(如果需要)
- 发送请求
7.1.新增文档
7.2.查询文档
7.3.更新文档
7.4.删除文档
7.5.批量导入文档
elasticsearch搜索功能
1.DSL查询分类和基本语法
1.1.查询分类
elasticsearch提供了基于JSON的DSL来定义查询。
常见的查询分类包括:
- 查询所有:查询出所有数据,一般测试用。例如:match_all
- 全文(full_text)检索查询:利用分词器对用户输入内容分词,然后如倒排索引库中匹配。如:
- match_query
- multi_match_query
- 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。如:
- ids
- range
- term(某个值==?)
- 地理(geo)查询:根据经纬度查询。如:
- geo_distance
- geo_bounding_box
- 复合(compound)查询:可以将上述各种查询条件组合起来。合并查询条件。例如:
- bool
- function_score
1.2.查询的基本语法
查询三要素:查询类型、查询条件、条件值
1.3.全文检索查询
全文检索查询,会对用户输入的内容分词,常用于搜索框搜索。
1.4.精确查询
一般是查询keyword、数值、日期、boolean等类型字段。
所以一般不会被分词,常见的类型:
- term:根据词条值精确查找
- range:根据值的范围查询
1.5.地理查询
根据经纬度查询,常见的使用场景:
- 携程:搜索我附近的酒店
- 滴滴:搜索我附件的出租车
- 微信:搜索我附近的人
常见的类型:
-
geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档
合适一定范围的所有信息,例如:地图找房
-
geo_distance:查询到指定中心点小于某个距离值的所有文档
附近的概念
1.6 复合(compound)查询
复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑,例如:
function score
算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价
相关性算分
可以修改文档的相关性算分(query score),根据新得到的算分排序。
案例:
总结
复合查询 Boolean query
布尔查询是一个或多个查询子句的组合。组合方式有:
- must:必须匹配每个子查询,类似【与】【and】
- should:选择性匹配子查询,类似【或】【or】
- must_not:必须不匹配,不参与算分,类似【非】【!=】
- filter:必须匹配,但是不参与算分
案例:
2.搜索结果的处理
2.1.排序
elasticsearch 支持对搜索结果的排序,默认根据相关度算分(_score)来排序。
可以排序的字段类型有:
- keyword类型
- 数值类型
- 地理坐标类型
- 日期类型
2.2.分页
elasticsearch 默认情况下只返回top10的数据。
如果需要更多数据就需要修改分页参数:
通过修改from、size参数来控制返回的分页结果:
深度分页问题:
ES是分布式的,所以会面临深度分页问题
深度分页解决方案:
- search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。推荐使用的方式。
- scroll:原理将排序数据形成快照,保存在内存。官方已不推荐使用
总结:
2.3.高亮
高亮:就是在搜索结果中把关键字突出显示。
原理:
- 将搜索结果中的关键字用标签标记出来
- 在页面中给标签添加css样式
语法:
注意:
高亮查询,默认情况下,ES搜索字段必须与高亮字段一致;
但是可通过require_field_match属性配置;
总结:
3.RestClient 查询文档
3.1.快速入门
实现的3步法:
- 准备request
- 准备DSL
- 发送请求
通过match_all来演示基本的API:
结果的解析:
总结:
3.2.全文检索查询
3.3.精确查询
3.4.复合查询
3.5.排序、分页、高亮
-
排序和分页
搜索结果的排序和分页是与query同级的参数:
-
高亮
高亮API包括请求DSL构建和结果解析2部分
DSL构建:
实现:但是结果并没有高亮
高亮结果解析:高亮需要单独解析
黑马旅游案例
1.酒店的搜索和分页
实现:
2.酒店结果的过滤
分析设计:
-
修改接收参数实体
-
分析业务条件
实现:
3.我周边的酒店
分析:
距离排序与普通字段排序的区别:
实现:
4.酒店的竞价排名
分析:
实现:
深入-数据聚合
1.聚合的种类
聚合(aggregations)可以实现对文档数据的统计、分析、运算。
聚合常见的3个种类:
-
桶(bucket)聚合:用来对文档做分组;
不能是分词的字段;必须是keyword、数值、日期、boolean
- termAggregation:按照文档字段值分组
- date Histogram:按照日期阶梯分组,例如:一周为一组。
-
度量(metric)聚合:用以计算一些值,比如:最大值、最小值、平均值。
- avg:求平均值
- max:求最大值
- min:求最小值
- stats:同时求max、min、avg、sum等
-
管道(pipeline)聚合:其它聚合的结果为基础做聚合
2.DSL实现聚合
2.1. 实现Bucket聚合
-
聚合实现
-
Bucket聚合-结果排序
-
Bucket聚合-限定范围
-
总结
2.2.实现Metrics聚合
-
聚合实现和排序
3.RestClient实现聚合
聚合结果的解析:
多条件聚合-案例:
深入-自动补全
1.安装拼音分词器
安装拼音分词器:
2.自定义分词器
elasticsearch中分词器(analyzer)的组成包含三部分:
- character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符。
- tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart。
- tokenizer filter:将tokenizer输出的词条做进一步处理;例如大小写转换、同义词处理、拼音处理等。
语法:
必须在创建索引库时,进行自定义分词器的设置:
注意事项-同义词:
注意事项-同义词-解决方案:
总结:
3.自动补全查询
语法:
4.实现酒店搜索框自动补全
案例分析:
验证:
5.RestClient实现自动补全查询
结果解析:
6. 案例实现搜索框自动补全查询
深入-数据同步
1.数据同步思路分析
分析:
elasticsearch中的数据来自于数据库,因此数据发生改变时,ES也必须跟着改变,
这个就是es与数据库之间的数据同步。
**方案一:**同步调用
依次操作、数据耦合
**方案二:**异步通知
比较推荐、依赖MQ、实现复杂度提升
**方案三:**监听binlog
需开启数据库的binlog,数据库压力增加,增加了中间件,复杂度高
binlog:mysql可开启binlog,binlog可记录数据的变动
canal:可监听binlog
总结:
2.MQ实现数据同步(rabbitmq)
案例:
实现和分析:
消息模型:
实现步骤:
- 声明交换机和队列以及key的绑定(一般在消费者端)
- 发送MQ消息
- 监听MQ消息
- 测试
深入-集群
1.搭建ES集群
问题:
单机的ES做数据存储,必然2个问题:
- 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点
- 单点故障问题:将分片数据在不同节点备份(replica)
搭建集群:
计划利用docker模拟3个es的节点。
部署es集群可以直接使用docker-compose来完成。
集群状态的监控:cerebro
分片和备份:
-
kibana:
-
cerebro:
2.集群的职责和脑裂
2.1.ES集群的节点角色
一个典型的ES集群一定是把每个节点的职责拆分成不同的节点,干不同的事!!
2.2.ES集群的脑裂
2.3.总结
3.分布式新增和查询流程
3.1.分布式存储
3.2.分布式新增
新增文档流程:
3.3.分布式查询
查询文档流程:
4.ES集群的故障转移
当节点恢复后,数据也会重新迁移回来!!
总结: