ElasticSearch
ES是一个开源的分布式搜索引擎,可用来实现搜索、日志统计、分析、系统监控,ES易于扩展可以轻松扩展到上百台服务器处理PB(1PB=1024TB、1TB=1024GB)级别的数据,ES自身携带分布式协调管理功能,但仅支持JSON文件格式。
ElasticSearch理论:
索引:在ES中一个索引对应一组相关文档的存储单元,可以被看作一种类似于数据库中的表结构,用于存储相类似的文档,每个文档都属于一个索引,索引中的文档用来被搜索和分析。
索引分片:将一个完整的索引分成多个的过程,每个分片本身是一个独立的索引,拥有自己的设置、映射、文档。ES通过将索引划分为多个分片来允许大规模存储,并且能够水平扩展,每个分片可分布在集群的不同节点上,默认情况下每个索引包含5个主分片。
索引副本:是每个分片的复制品,用于提供冗余和故障的恢复,副本分布在不同的节点上,从而增加了系统的可靠性和容错能力。
ElasticSearch核心概念:
节点:是集群中的单个服务器,用于存储数据并参与集群的索引和搜索功能。每个节点都有自己的名称和唯一标识符。
集群:由一个或多个节点组成的一组服务器,它们共同存储项目的整个数据,集群提供了高可用性和横向扩展性。
分片:将索引中的数据分割成多个部分,用于提高性能和扩展性,每个分片可以被存储在集群中一个或多个节点上。
复制:为了数据的高可用性和容错性,每个分片都会有一个或多个副本分片,这些分片会被存储在不同的节点上。
索引:是用于存储数据的地方,类似于关系型数据库中的数据,它是一种用于存储相似性质的文档的数据结构。
类型:在ES6.0之前用于组织索引内部文档的一种方式,在ES7.0版本之后已经被废弃,推荐使用单一索引多字段代替。
文档:是ES中的基本数据单元,类似于关系型数据库中的行(也就是一行数据),每个文档都是一个JSON对象,它们被存储在索引中并可以被搜索。
字段:是ES中文档的组成部分,类似于关系型数据库中的列,每个字段都有自己的数据类型(不如:文本型、数值型等),并且包含特定的数据。
映射:定义了索引中的每个字段的数据类型和属性,它相当于关系型数据库中的模式,告诉ES如何处理索引的每个字段。
安装elasticsearch
拉取镜像:
注:镜像尽量大于7.12.1
docker pull elasticsearch:7.12.1
创建ES网络:
docker network create es-network
找到usr目录,创建elasticsearch目录,并进入elasticsearch目录,创建data、plugins文件夹
返回上一级,修改挂载文件的权限
创建容器:
注:如果发现运行不了,检查是否有多余的空格!
docker run -d --name elasticsearch --net=es-network -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e xpack.security.authc.api_key.enabled=true -e "ES_JAVA_OPTS=-Xms50m -Xmx512m" -v es-data:/usr/elasticsearch/data -v es-plugins:/usr/elasticsearch/plugins docker.elastic.co/elasticsearch/elasticsearch:7.12.1
docker run
-d 后台运行
--name elasticsearch 给容器起一个别名
--net=es-network 指定容器链接到名为es-network的网络上面
-p 9200:9200 主机和容器之间的端口映射,9200用于程序调用使用
-p 9300:9300 主机和容器之间的端口映射,9300用于es集群之间的通信
-e "discovery.type=single-node" 配置单节点启动发现的环境变量
-e xpack.security.authc.api_key.enabled=true 启动API密钥认证功能
-e "ES_JAVA_OPTS=-Xms50m -Xmx512m" 指定JAVA虚拟机最小堆内存为50M最大为512M
-v es-data:/usr/elasticsearch/data 挂载数据目录卷
-v es-plugins:/usr/elasticsearch/plugins 挂载插件目录卷
docker.elastic.co/elasticsearch/elasticsearch:7.12.1 指定运行的镜像:版本
安装成功的校验:
curl http://localhost:9200
给ES设置访问密码:
1. 进入容器内,找到/usr/share/elasticsearch/config目录
2. 需要vi编辑elasticsearch.yml文件,添加
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
3. 回到宿主机(Ctrl+Q+P)重启ES容器
4. 再次进入容器,输入命令,设置密码
./bin/elasticsearch-setup-passwords interactive
注:密码要输入多次必须一样
5. 退出容器到宿主机,重启ES容器
访问:
ip:9200
47.108.49.150:9200
默认用户名:elastic
访问成功:
安装可视化工具kibana
拉取镜像:
docker pull kibana:7.12.1
注:与ES版本相对应
创建kibana网络:
docker network create kibana-network
执行容器创建命令:
docker run -d \
--name kibana \
--net=kibana-network \
-e ELASTICSEARCH_HOSTS=http://47.108.49.150:9200 \
-p 5601:5601 \
docker.elastic.co/kibana/kibana:7.12.1
进入容器 :
docker exec -it 容器id /bin/bash
找到/usr/share/kibana目录的kibana.yml文件
编辑kibana.yml文件,添加
i18n.locale: "zh-CN"
elasticsearch.username: "elastic"
elasticsearch.password: "xxxxx"
(Ctrl+Q+P)退出容器,再重启容器
ElasticSearch基础语法
创建索引
PUT /helloworld
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
, "mappings": {
"properties": {
"name":{
"type": "text"
},
"value":{
"type": "text"
}
}
}
}
PUT /helloworld
{
"settings": {
"number_of_shards": 1, 主分片数
"number_of_replicas": 1 副分片数
}
, "mappings": {
"properties": {
"name":{
"type": "text" 文本类型
},
"value":{
"type": "text" 文本类型
}
}
}
}
创建数据库
PUT /my_es
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"title":{"type": "text"},
"content":{"type": "text"},
"author":{"type": "text"},
"time":{"type": "date"}
}
}
}
PUT /my_es 索引名
{
"settings": {
"number_of_shards": 2, 主分片
"number_of_replicas": 2 副分片
},
"mappings": {
"properties": {
"title":{"type": "text"}, 设置类型、属性
"content":{"type": "text"},
"author":{"type": "text"},
"time":{"type": "date"}
}
}
}
添加文档
POST /my_es/_doc
{
"title":"",
"content":"",
"author":"",
"time":""
}
POST /my_es/_doc
{
"title":"震惊平成三流氓被吊",
"content":"在异常的平行时空里,平成三流氓被塔尔塔罗斯封印了",
"author":"圆谷",
"time":"2023-12-18T11:46:33"
}
语法规则
_doc 用于早期的ES版本中,同一个索引中单独集合映射类型,从8.x版本开始已全面废弃
_index 创建新索引,index索引是创建一个命名空间,将相关文档聚合在一起
_create 创建新索引,是创建一个新的文档,并将其添加到指定索引中
_update 用于更新文档中的一部分内容
_delete 删除文档
查询所有
GET /my_es/_search
单个条件查询
GET /my_es/_search
{
"query": {
"match": {
"title": ""
}
}
}
GET /my_es/_search
{
"query": {
"match": {
"title": "流氓"
}
}
}
返回结果
{
"took" : 88, 操作花费的毫秒数,请求耗时
"timed_out" : false, 是否超时
"_shards" : { 分片信息(包含成功的分片数量和失败的分片数量)
"total" : 2, 总分分片数(总命中数)
"successful" : 2, 搜索成功的分片数
"skipped" : 0, 没有搜索/跳过的分片数
"failed" : 0 搜索失败的分片数
},
"hits" : { 搜索结果集
"total" : { 返回多少数据
"value" : 1, 一个一条数据
"relation" : "eq" 过滤语法
},
"max_score" : 2.9424872, 最高匹配得分
"hits" : [
{
"_index" : "taobao_goods", 索引名
"_type" : "_doc", 文档类型(8.0以弃用)
"_id" : "M3ftgIwBaKUte9lFp1EY", 唯一标识符
"_score" : 2.9424872, 匹配度得分
"_source" : { 实际的内容
"id" : "1",
"name" : "凯撒贝利亚",
"discription" : "黑暗贝老黑——复活重生者",
"price" : "5",
"stock" : "10"
}
}
]
}
}
多条件查询
Get /taobao_goods/_search
{
"query":{
"bool": { 多条件查询的一种方式
"must": [ 必须满足以下条件相当于sql中的and
{"match": {"name": "贝利亚"}},
{"match": {"discription":"复活重生者"}}
]
}
}
}
must 必须都匹配相当于逻辑的and
must_not 条件必须都不匹配相当于逻辑的not
should 条件可以匹配,但不是必须相当于逻辑上的or
filter 条件必须匹配,常用于过滤操作
更新索引
_doc 覆盖方式完成更新(8.0后移除)
POST /taobao_goods/_doc/M3ftgIwBaKUte9lFp1EY
{
"doc":{
"stock" : "30"
}
}
这种写法会重写原有的数据结构(慎用)
POST /taobao_goods/_update/M3ftgIwBaKUte9lFp1EY
{
"doc":{
"num":"2"
}
}
只会修改对应的字段
如果没有这个字段会直接添加
删除文档
通过ES的id删除
DELETE /taobao_goods/_doc/_id
如:
DELETE /taobao_goods/_doc/M3ftgIwBaKUte9lFp1EY
通过mysql的id删除
POST /taobao_goods/_delete_by_query
{
"query":{
"match":{"id":"2"}
}
}
批量删除
POST /taobao_goods/_delete_by_query
{
"query":{
"match_all":{}
}
}