Elasticsearch(看这一篇就够了)
目录:
- Elasticsearch
-
- 介绍
- 正排索引和倒排索引
- Elasticsearch安装
-
- 安装ES服务
- 安装服务
- 安装kibana
- 索引操作
-
- 创建索引
- 查询索引库
- 修改索引库
- 删除索引库
- Elasticsearch常用操作
-
- 文档操作
-
- 新增文档
- 查询文档
- 删除文档
- 根据id批量查询文档
- 查询所有文档
- 修改文档部分字段
- 域的属性
- 分词器
-
- 默认分词器
- IK分词器
- 拼音分词器
- 自定义分词器
- Elasticsearch搜索文档
-
- 搜索方式
- SpringDaraES案例
-
- 使用Repository继承的方法查询文档
- 使用DSL语句查询文档
- 按照规则命名方法查询文档
- 分页查询
- 结果排序
- template工具类
-
- 操作索引
- 操作文档
- 查询文档
- 复杂条件查询
- 分页查询
- 结果排序
- Elasticsearch集群
-
- 搭建集群
- 测试集群状态
- 故障应对和水平扩容
- 内存设置
- 磁盘选择
- 分片策略
- Elasticsearch案例
-
- 需求说明
- ES自动补全
- 创建索引
- mysql数据导入es
- 项目搭建
- 创建实体类
- 创建Repository接口
- 自动补全功能
- 搜索关键字功能
- 创建Controller类
- 前端页面
Elasticsearch
介绍
Elasticsearch是一个全文检索服务器
全文检索是一种非结构化数据的搜索方式
-
结构化数据:指具有固定格式固定长度的数据,如数据库中的字段。
-
非结构化数据:指格式和长度不固定的数据,如电商网站的商品详情。
结构化数据一般存入数据库,使用sql语句即可快速查询。但由于非结构化数据的数据量大且格式不固定,我们需要采用全文检索的方式进行搜索。全文检索通过建立倒排索引加快搜索效率。
正排索引和倒排索引
索引
将数据中的一部分信息提取出来,重新组织成一定的数据结构,我们可以根据该结构进行快速搜索,这样的结构称之为索引。
索引即目录,例如字典会将字的拼音提取出来做成目录,通过目录即可快速找到字的位置。
索引分为正排索引和倒排索引。
正排索引(正向索引)
将文档id建立为索引,通过id快速可以快速查找数据。如数据库中的主键就会创建正排索引。
倒排索引(反向索引)
非结构化数据中我们往往会根据关键词查询数据。此时我们将数据中的关键词建立为索引,指向文档数据,这样的索引称为倒排索引。
Elasticsearch安装
安装ES服务
准备工作
1.准备一台搭载有CentOS7系统的虚拟机,使用XShell连接虚拟机
2.关闭防火墙,方便访问ES
#关闭防火墙:systemctl stop firewalld.service#禁止防火墙自启动:systemctl disable firewalld.service
3.配置最大可创建文件数大小
#打开系统文件:vim /etc/sysctl.conf#添加以下配置:vm.max_map_count=655360#配置生效:sysctl -p
- 由于ES不能以root用户运行,我们需要创建一个非root用户,此处创建一个名为es的用户:
#创建用户:useradd es
安装服务
-
使用rz命令将linux版的ES上传至虚拟机
-
解压ES
#解压:tar -zxvf elasticsearch-8.10.4-linux-x86_64.tar.gz#重命名:mv elasticsearch-8.10.4 elasticsearch1#移动文件夹:mv elasticsearch1 /usr/local/#es用户取得该文件夹权限:chown -R es:es /usr/local/elasticsearch1
- 启动ES服务:
#切换为es用户:su es#进入ES安装文件夹:cd /usr/local/elasticsearch1/bin/#启动ES服务:./elasticsearch
- 当启动成功,可以看到类似以下的日志输出。首次启动Elasticsearch,默认会启用安全配置功能,启用身份认证和授权,内置超级用户elastic,并生成默认密码,此时要注意保存,否则之后启动不会再显示。
# 重置默认密码:cd /usr/local/elasticsearch1/bin/./elasticsearch-reset-password -u elastic# 自定义密码:cd /usr/local/elasticsearch1/bin/./elasticsearch-reset-password --username elastic -i
- 连接ES,查询ES服务是否启动成功
# 参数 --cacert指定了证书curl --cacert /usr/local/elasticsearch1/config/certs/http_ca.crt -u elastic https://localhost:9200
安装kibana
Kibana是一款开源的数据分析和可视化平台,设计用于和Elasticsearch协作。我们可以使用Kibana对Elasticsearch索引中的数据进行搜索、查看、交互操作。
-
使用rz工具将Kibana压缩文件上传到Linux虚拟机
-
解压
tar -zxvf kibana-8.10.4-linux-x86_64.tar.gz -C /usr/local/
- 修改配置
# 进入Kibana解压路径cd /usr/local/kibana-8.10.4/config# 修改配置文件vim kibana.yml# 加入以下内容# 主机IP,服务名server.host: \"虚拟机IP\"server.name: \"kibana\"
- 启动:
kibana不能以root用户运行,我们给es用户设置kibana目录的权限,并使用es用户运行kibana
# 给es用户设置kibana目录权限chown -R es:es /usr/local/kibana-8.10.4/# 切换为es用户su es# 启动kibanacd /usr/local/kibana-8.10.4/bin/./kibana
- 访问kibana:http://虚拟机IP:5601
首次访问Kibana管理台会提示输入ES生成的token秘钥,可以在ES首次启动日志中找。
如果token已失效或不正确,你也可以重新生成token。
# 进入es安装目录cd /usr/local/elasticsearch1/bin# 重新生成kibana的token.elasticsearch-create-enrollment-token --scope kibana
紧接着输入登录账号 elastic,密码也同样是从ES首次启动日志中找。
- 点击
Management
=>Index Management
可以查看es索引信息。
索引操作
创建索引
Elasticsearch是使用RESTful风格的http请求访问操作的,请求参数和返回值都是Json格式的,我们可以使用kibana发送http请求操作ES。
创建没有结构的索引
路径:ip地址:端口号/索引名
注:在kibana中所有的请求都会省略ip地址:端口号,之后的路径我们省略写
ip地址:端口号
格式:
PUT /索引库名称{ \"mappings\": { \"properties\": { \"字段名\":{ \"type\": \"text\", \"analyzer\": \"ik_smart\" }, \"字段名2\":{ \"type\": \"keyword\", \"index\": \"false\" }, \"字段名3\":{ \"properties\": { \"子字段\": { \"type\": \"keyword\" } } }, // ...略 } }}
基本语法:
- 请求方式:PUT
- 请求路径:/索引库名,可以自定义
- 请求参数:mapping映射
格式:
为索引添加结构
POST /索引名/_mapping{ \"properties\":{ \"域名1\":{ \"type\":域的类型, \"store\":是否存储, \"index\":是否创建索引, \"analyzer\":分词器 }, \"域名2\":{ ... } }}
PUT /索引库名称{ \"mappings\": { \"properties\": { \"字段名\":{ \"type\": \"text\", \"analyzer\": \"ik_smart\" }, \"字段名2\":{ \"type\": \"keyword\", \"index\": \"false\" }, \"字段名3\":{ \"properties\": { \"子字段\": { \"type\": \"keyword\" } } }, // ...略 } }}
查询索引库
基本语法:
- 请求方式:GET
- 请求路径:/索引库名
- 请求参数:无
格式:
GET /索引库名
修改索引库
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping
。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。
语法说明:
PUT /索引库名/_mapping{ \"properties\": { \"新字段名\":{ \"type\": \"integer\" } }}
删除索引库
语法:
-
请求方式:DELETE
-
请求路径:/索引库名
-
请求参数:无
格式:
DELETE /索引库名
Elasticsearch常用操作
文档操作
新增文档
POST /索引/_doc/[id值]{ \"field名\":field值}POST /索引库名/_doc/文档id{ \"字段1\": \"值1\", \"字段2\": \"值2\", \"字段3\": { \"子属性1\": \"值3\", \"子属性2\": \"值4\" }, // ...}
示例:
POST /jjy/_doc/1{ \"info\": \"jjy最牛啦\", \"email\": \"zy@itcast.cn\", \"name\": { \"firstName\": \"云\", \"lastName\": \"赵\" }}
注:id值不写时自动生成文档id,id和已有id重复时修改文档
查询文档
GET /索引/_doc/id值
示例:
GET /jjy/_doc/1
删除文档
DELETE /索引/_doc/id值
示例:
DELETE /jjy/_doc/1
根据id批量查询文档
GET /索引/_mget{ \"docs\":[ { \"_id\":id值}, { \"_id\":id值} ] }
示例:
GET /jjy/_mget{ \"docs\":[ { \"_id\":1}, { \"_id\":2} ] }
查询所有文档
GET /索引/_search{ \"query\": { \"match_all\": { } }}
示例:
GET /jjy/_search{ \"query\": { \"match_all\": { } }}
修改文档部分字段
POST /索引/_update/1/{ \"doc\":{ 域名:值 } }
示例:
POST /jjy/_update/id值/{ \"doc\":{ info:\"jjy好厉害哦\" } }
注:
Elasticsearch执行删除操作时,ES先标记文档为
deleted
状态,而不是直接物理删除。当ES存储空间不足或工作空闲时,才会执行物理删除操作。Elasticsearch执行修改操作时,ES不会真的修改Document中的数据,而是标记ES中原有的文档为deleted状态,再创建一个新的文档来存储数据。
域的属性
index
该域是否创建索引。只有值设置为true,才能根据该域的关键词查询文档。// 根据关键词查询文档GET /索引名/_search{ \"query\":{ \"term\":{ 搜索字段: 关键字 } }}
type
域的类型
store
是否单独存储。如果设置为true,则该域能够单独查询。
// 单独查询某个域:GET /索引名/_search{ \"stored_fields\": [\"域名\"]}
分词器
默认分词器
ES文档的数据拆分成一个个有完整含义的关键词,并将关键词与文档对应,这样就可以通过关键词查询文档。要想正确的分词,需要选择合适的分词器。
standard analyzer
:Elasticsearch默认分词器,根据空格和标点符号对英文进行分词,会进行单词的大小写转换。
- 查看分词效果
GET /_analyze{ \"text\":测试语句, \"analyzer\":分词器}
IK分词器
IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。提供了两种分词算法:
-
ik_smart:最少切分
-
ik_max_word:最细粒度划分
安装IK分词器
-
关闭es服务
-
使用rz命令将ik分词器上传至虚拟机
注:ik分词器的版本要和es版本保持一致。
- 解压ik分词器到elasticsearch的plugins目录下
unzip elasticsearch-analysis-ik-8.10.4.zip -d /usr/local/elasticsearch1/plugins/analysis-ik
- 启动ES服务
su es#进入ES安装文件夹:cd /usr/local/elasticsearch1/bin/#启动ES服务:./elasticsearch
测试分词器效果
GET /_analyze{ \"text\":\"测试语句\", \"analyzer\":\"ik_smart/ik_max_word\"}
IK分词器词典
IK分词器根据词典进行分词,词典文件在IK分词器的config目录中。
-
main.dic:IK中内置的词典。记录了IK统计的所有中文单词。
-
IKAnalyzer.cfg.xml:用于配置自定义词库。
IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key=\"ext_dict\">ext_dict.dic</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key=\"ext_stopwords\">ext_stopwords.dic</entry> <!--用户可以在这里配置远程扩展字典 --> <!-- <entry key=\"remote_ext_dict\">words_location</entry> --> <!--用户可以在这里配置远程扩展停止词字典--> <!-- <entry key=\"remote_ext_stopwords\">words_location</entry> --></properties>
拼音分词器
拼音分词器可以将中文分成对应的全拼,全拼首字母等。
安装拼音分词器
-
关闭es服务
-
使用rz命令将拼音分词器上传至虚拟机
注:拼音分词器的版本要和es版本保持一致。
解压pinyin分词器到elasticsearch的plugins目录下
unzip elasticsearch-analysis-pinyin-8.10.4 -d /usr/local/elasticsearch1/plugins/analysis-pinyin
启动ES服务
su es#进入ES安装文件夹:cd /usr/local/elasticsearch1/bin/#启动ES服务:./elasticsearch
测试分词效果
GET /_analyze{ \"text\":测试语句, \"analyzer\":\"pinyin\"}
自定义分词器
真实开发中我们往往需要对一段内容既进行文字分词,又进行拼音分词,此时我们需要自定义ik+pinyin分词器。
创建自定义分词器
在创建索引时自定义分词器
PUT /索引名{ \"settings\" : { \"analysis\" : { \"analyzer\" : { \"ik_pinyin\" : { //自定义分词器名 \"tokenizer\":\"ik_max_word\", // 基本分词器 \"filter\":\"pinyin_filter\" // 配置分词器过滤 } }, \"filter\" : { // 分词器过滤时配置另一个分词器,相当于同时使用两个分词器 \"pinyin_filter\" : { \"type\" : \"pinyin\", // 另一个分词器 // 拼音分词器的配置 \"keep_separate_first_letter\" : false, // 是否分词每个字的首字母 \"keep_full_pinyin\" : true, // 是否分词全拼 \"keep_original\" : true, // 是否保留原始输入 \"remove_duplicated_term\" : true // 是否删除重复项 } } } }, \"mappings\":{ \"properties\":{ \"域名1\":{ \"type\":域的类型, \"store\":是否单独存储, \"index\":是否创建索引, \"analyzer\":分词器 }, \"域名2\":{ ... } } }}
测试自定义分词器
GET /索引/_analyze{ \"text\": \"你好程序员\", \"analyzer\": \"ik_pinyin\"}
Elasticsearch搜索文档
添加一些文档数据
PUT /students{ \"mappings\":{ \"properties\":{ \"id\": { \"type\": \"integer\", \"index\": true }, \"name\": { \"type\": \"text\", \"store\": true, \"index\": true, \"analyzer\": \"ik_smart\" }, \"info\": { \"type\": \"text\", \"store\": true, \"index\": true, \"analyzer\": \"ik_smart\" } } }}POST /students/_doc/{ \"id\":1, \"name\":\"程序员\", \"info\":\"I love baizhan\"}POST /students/_doc/{ \"id\":2, \"name\":\"美羊羊\", \"info\":\"美羊羊是羊村最漂亮的人\"}POST /students/_doc/{ \"id\":3, \"name\":\"懒羊羊\", \"info\":\"懒羊羊的成绩不是很好\"}POST /students/_doc/{ \"id\":4, \"name\":\"小灰灰\", \"info\":\"小灰灰的年纪比较小\"}POST /students/_doc/{ \"id\":5, \"name\":\"沸羊羊\", \"info\":\"沸羊羊喜欢美羊羊\"}POST /students/_doc/{ \"id\":6, \"name\":\"灰太狼\", \"info\":\"灰太狼是小灰灰的父亲,每次都会说我一定会回来的\"}
搜索方式
match_all:查询所有文档
{ \"query\":{ \"match_all\":{ } }}
match:全文检索。将查询条件分词后再进行搜索。
{ \"query\":{ \"match\":{ 搜索字段:搜索条件 } }}
注:在搜索时关键词有可能会输入错误,ES搜索提供了自动纠错功能,即ES的模糊查询。使用match方式可以实现模糊查询。模糊查询对中文的支持效果一般,我们使用英文数据测试模糊查询。
{ \"query\": { \"match\": { \"域名\": { \"query\": 搜索条件, \"fuzziness\": 最多错误字符数,不能超过2 } } }}
range:范围搜索。对数字类型的字段进行范围搜索
{ \"query\":{ \"range\":{ 搜索字段:{ \"gte\":最小值