一、Elasticsearch
简介
Elasticsearch 8
简称 es8
是一款非常强大的开源搜索引擎,具备非常多强大功能,网上对其有非常详细的定义这里不多做赘述,总之它是在你查询语句性能达到瓶颈,并且使用了索引、缓存等手段仍然无法突破的情况下的另一种十分有效的解决方案
基本概念
Elasticsearch
是一个基于 Lucene
的分布式搜索引擎,它不仅可以进行全文搜索,还能够用于分析大量数据。它的核心概念主要包括以下几个:
1. 索引(Index)
Index
是 Elasticsearch
中的最基本单元,类似于关系型数据库中的“数据库”。每个索引都包含许多文档,存储了我们要进行搜索的数据。可以把它理解为数据的集合。
2. 文档(Document)
文档是具体的数据实体,存储在索引中。它类似于数据库中的“行”。每个文档是一个JSON格式的对象,包含了具体的信息,比如用户信息、产品详情等。
3. 类型(Type)
在 Elasticsearch 6
版本及之前,索引中可以包含不同类型的文档(Type
),类似于数据库中的表。但是在 Elasticsearch 7
之后,Type
被逐渐弃用,每个索引只能有一个类型。
4. 字段(Field)
字段(Field
),就是JSON文档中的字段,类似数据库中的列(Column
)
5. 映射(Mapping)
Mapping
(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema
)
6. DSL
DSL
是 elasticsearch
提供的 JSON
风格的请求语句,用来操作 elasticsearch
,实现 CRUD
二、安装
我们使用 docker
的方式来安装 es8
https://hub.docker.com/_/elasticsearch/tags
1.拉取 ElasticSearch 镜像
我这边选择的版本是以 8 以上为主,所以使用8.8.1
,linux
的发行版是 ubantu
docker pull elasticsearch:8.8.1
2.创建并运行容器
使用以下命令创建一个新的 elasticsearch
容器并将其启动:
docker run --name some-elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -d elasticsearch:8.8.1
--name some-elasticsearch
:给容器起个名字some-elasticsearch
,方便管理。-p 9200:9200
:将本地的9200
端口映射到容器内的9200
端口(这是Elasticsearch
对外提供RESTful
接口的端口)。-p 9300:9300
:将本地的9300
端口映射到容器内的9300
端口(这是集群节点之间通信的端口)。-e "discovery.type=single-node"
表示 指定Elasticsearch
节点在单节点模式下运行,即启动一个独立的Elasticsearch
实例而不是一个多节点集群-d
表示后台运行。
假如 pull
不下来,给配置文件添加以下镜像地址
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.211678.top",
"https://docker.1panel.live",
"https://hub.rat.dev",
"https://docker.m.daocloud.io",
"https://do.nark.eu.org",
"https://dockerpull.com",
"https://dockerproxy.cn",
"https://docker.awsl9527.cn"
]
}
重启 docker
systemctl daemon-reload
systemctl restart docker
3.测试,是否启动成功
注意: es8.0以上默认开启了 ssl 认证
直接访问 : http://xxx.xxx.xxx:9200
是无法访问的,需要访问 https
,或者关闭 SSL
认证
自 Elasticsearch 7.8.0
版本开始,Elasticsearch
不再提供默认的用户名和密码。相反,它采用了内置安全特性,并引入了超级用户(superuser)角色和内置用户(built-in users)概念来管理访问控制。
在新安装的情况下,您需要设置一个初始的内置用户以及相关的登录凭据。可以通过修改 Elasticsearch
的配置文件 elasticsearch.yml
来完成此操作。
-
将容器内容的配置文件复制到本地修改:
docker cp some-elasticsearch:/usr/share/elasticsearch/config/elasticsearch.yml /root/elasticsearch.yml
-
在本地编辑文件
vim /root/elasticsearch.yml
打开
elasticsearch.yml
文件 找到xpack.security.enabled: true
改为xpack.security.enabled: false
,这样就可以直接使用http
访问,并且不需要账号密码鉴权,这个设置看个人情况,如果是生产环境建议开始开启https
和账号密码鉴权 -
将修改后的文件复制回容器:
docker cp /root/elasticsearch.yml some-elasticsearch:/usr/share/elasticsearch/config/elasticsearch.yml
-
重启容器
docker restart some-elasticsearch
在访问
http://127.0.0.1:9200
4. 安装ElastIcSearch 可视化管理界面 Kibana
-
拉取Kibana镜像
docker pull kibana:8.8.1
-
启动
Kibana
docker run --name some-kibana -p 5601:5601 -d kibana:8.8.1
5601
表示Kibana
访问端口,开启主机与容器端口映射 -
配置
Kibana
将容器内容的配置文件复制到本地修改:
docker cp some-kibana:/usr/share/kibana/config/kibana.yml /root/kibana.yml ``` 在本地编辑文件 ```bash vim kibana.yml
- 打开
kibana.yml
文件 增加csp.strict: false
设置 CSP 启用Kibana
模式,如果为true
那么会对浏览器进行安全检查 - 增加
i18n.locale: "zh-CN"
配置中文 - 将
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
改为 具体Elasticsearch
通信地址
将修改后的文件复制回容器:
docker cp /root/kibana.yml some-kibana:/usr/share/kibana/config/kibana.yml
- 打开
-
重启
kibana
docker restart some-kibana
-
访问
Kibana
http://xxx.xxx.xxx:5601
点击左侧边栏开发工具打可以打开控制台
5. IK 分词器安装
Elasticsearch
在创建倒排索引时,需要对文档进行分词;在搜索时对用户的输入内容进行分词,但默认的分词效果不好,可以安装 IK 分词来处理。
主要有两种方式:在线安装和离线安装
在线安装
1、进入容器内部
docker exec -it some-elasticsearch bash
2、下载安装
注:下载的包一定要和 ElasticSearch
的版本一致。
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.8.1/elasticsearch-analysis-ik-8.8.1.zip
稍等一会,输入y,确认安装
3、退出并启动
exit
docker restart es
6. 验证分词器
IK 分词主要有两种模式
ik_smart
最少切分 粗粒度切分 智能切分ik_max_word
最细切分 最新粒度切分
举例如下:
ik_smart
粗粒度分词,只展示出 程序员
POST /_analyze
{
"text":"1024程序员节",
"analyzer":"ik_smart"
}
ik_max_word
细粒度分词,展示出 程序员、程序、员
POST /_analyze
{
"text":"1024程序员节",
"analyzer":"ik_max_word"
}
离线安装
1、查询数据卷目录
// 输入数据卷
docker volume inspect es-plugins
插件安装需要获取 Elasticsearch
的 plugins
目录的挂载位置
2、上传 安装包到 指定位置
下载 elasticsearch-analysis-ik-8.8.1.zip
放到 第一步查询目录下,进行挂载,注意这里的版本选择的是 8.8.1
3、重启容器
// 重启
docker restart es
// 查看日志
docker logs -f es
三、基本操作
3.1 索引操作
Elasticsearch
采用 Rest
风格 API,因此其 API 就是一次 http 请求,你可以用任何工具发起 http 请求
1)创建索引
PUT /索引名称
{
"settings":{
"属性名":"属性值"
}
}
settings:索引库设置,可以定义索引库的属性,例如:分片数、副本数;也可以不设置,采用默认属性。
2)判断索引是否存在
HEAD/索引名称
3)查看单个索引
GET /索引名称
4)批量查看索引
GET /索引名称1,索引名称2...
5)查看所有索引
GET _all
GET /_cat/indices?v
6)打开、关闭索引
打开:
POST /索引名称/_open
关闭
POST /索引名称/_close
删除索引
DELETE /索引名称1,索引名称2...
3.2 映射操作
索引创建之后,等于有了关系型数据库中的 database
。Elasticsearch7.x
取消了索引 type
类型的设置,不允许指定类型,默认为 _doc
,但字段仍然是有的,需要设置字段的约束信息,叫做字段映射(mapping),字段的约束包括但不限于:
- 字段的数据类型
- 是否要存储
- 是否要索引
- 分词器
1)创建映射字段
PUT /test-index/_mapping
{
"properties": {
"字段名": {
"type": "类型",
"index": true,
"store": true,
"analyzer": "分词器"
}
}
}
- type:类型,可以是
text、long、short、date、integer、object
等 - index:是否索引,默认为
true
- store:是否存储,默认为
false
- analyzer:指定分词器
示例:
PUT /ygp-company-index
PUT /ygp-company-index/_mapping/
{
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"job": {
"type": "text",
"analyzer": "ik_max_word"
},
"logo": {
"type": "keyword",
"index": "false"
},
"payment": {
"type": "float"
}
}
}
2)映射属性详解
Type
Elasticsearch支持的数据类型非常丰富:
-
String
类型,可分为两种text
: 可分词,不可参与聚合keywork
: 不可分词,数据作为完整字段进行匹配,可以参与聚合
-
Numerical
:数值类型,分两类- 基本数据类型:
long、integer、short、byte、double、float、half_float
- 浮点数的高精度类型:
scaled_float
- 基本数据类型:
-
Date
:日期类型- elasticsearch 可以对日期格式化为字符串存储,但是建议存储为毫秒,存储为 long,节省空间。
-
Array
: 数组类型- 进行匹配时,任意一个元素满足,都认为满足
- 排序时,如果升序则用数组中最小值来排序,如果降序则用数组中的最大值来排序 Object:对象
{
"name":"Tome",
"age": 20,
"girl":{
"name":"Rose","age":20,
}
}
如果存储到索引库的是对象类型,例如上面的 girl
,会把 girl
变成两个字段:girl.name和girl.age
index
index影响字段的索引情况:
- true:字段会被索引,则可以用来进行搜索。默认值就是true。
- false:字段不会被索引,不能用来搜索
store
是否将数据进行独立存储 原始的文本会存储在_source里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source里面提取出来的,页可以独立存储某个字段,设置store:true;获取独立存储的字段要比从_source中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置,默认为false。
analyzer
指定分词器 一般处理中文会选择ik分词器:ik_max_word、ik_smart
3)映射操作
查看单个索引映射关系
GET /索引名称/_mapping
查看多个索引的映射
# 方式一
GET _mapping
# 方式二
GET all/_mapping
修改索引映射关系
PUT /索引名/_mapping
PUT /ygp-company-index/_mapping
{
"properties": {
"字段名": {
"type": "类型",
"index": true,
"store": true,
"analyzer": "分词器"
}
}
}
同时创建索引和设置映射
PUT /mcs-index
{
"settings": {
"索引库属性名": "索引库属性值"
},
"mappings": {
"properties": {
"字段名": {
"映射属性名": "映射属性值"
}
}
}
}
增加映射
POST /activity-index/_mapping
{
"properties": {
"activityType": {
"type": "keyword"
}
}
}
3.3 文档(doc)操作
文档,类比数据库中的每行数据,会根据规则创建索引,将来用于搜索;可以类比数据库中的一行数据。
1)新增文档
新增文档,id的生成方式有两种,手动指定或者自动生成。
新增文档(手动指定)
POST /索引名称/_doc/{id}
{
"field":"value"
}
新增文档(自动生成id)
POST /索引名称/_doc
{
"field":"value"
}
可以看到结果显示为: created
,代表创建成功。
另外,需要注意的是,在响应结果中有个 _id
字段,这个就是这条文档数据的 唯一标识 ,以后的增删改查都依赖这个 _id
作为唯一标示,这里是 Elasticsearch
帮我们随机生成的 id
2)查看单个文档
GET /索引名称/_doc/{id}
文档元数据解读: |元数据项| 含义| |---|---| |_index |document所属的index| |_type| document所属的type,Elasticsearch7.x默认type为_doc| |_id| 代表document的唯一标识,与index一起,可以唯一标识和定位一个document| |_version| document的版本号,Elasticsearch利用_version (版本号)的方式来确保应用中相互冲突的变更不会导致数据丢失。需要修改数据时,需要指定想要修改文档的version号,如果该版本不是当前版本号,请求将会失败| |_seq_no| 严格递增的顺序号,每个document一个,严格递增,保证后写入的doc的_seq_no大于先写入的_seq_no| |_primary_term| 任何类型的写操作,包括index、create、update和Delete,都会生成一个_seq_no。| |found| true/false 是否查找到文档| |_source| 存储原始文档|
3)查看所有文档
POST /索引名称/_search
{
"query": {
"match_all": {}
}
}
4)_source定制返回字段
某些业务场景下,我们不需要搜索引擎返回 _source
中的所有字段,可以使用 source
进行定制,如下,多个字段之间使用逗号分隔
GET /索引名称/_doc/{id}?_source=name
5)更新文档
更新所有属性
更新文档为PUT操作,更新时需要指定id
id对应的文档存在,则修改,id对应的文档不存在,则新增
PUT /ygp-company-index/_doc/9BlvdZIBo_i9DbGpUNi8
{
"name": "更新"
}
这条记录不存在,返回的 _result
属性显示的时创建
再次执行上面的命令,并将数据修改一下:
PUT /ygp-company-index/_doc/9BlvdZIBo_i9DbGpUNi8
{
"name": "更新2"
}
上面就是 Elasticsearch
使用 PUT
或者 POST
对文档进行更新(全部更新),如果指定 ID
的文档已经存在,则执行更新操作。
全部更新就是,Elasticsearch
首先将旧的文档标记为删除状态,然后添加新的文档,旧的文档不会立即消失,也无法访问;Elasticsearch
会在你继续添加更多数据的时候在后台清理已经标记为删除状态的文档。
局部更新
局部更新就是,只是修改某个字段
POST /ygp-company-index/_update/9BlvdZIBo_i9DbGpUNi8
{
"doc": {
"name": "更新3"
}
}
如果局部更新的文档不存在,则会返回异常
6)删除文档
根据id进行删除
DELETE /索引名称/_doc/{id}
根据查询条件删除
POST /ygp-company-index/_delete_by_query
{
"query": {
"match": {
"name": "更新3"
}
}
}
删除所有
POST /ygp-company-index/_delete_by_query
{
"query": {
"match_all": {}
}
}