Elasticsearch(7.x)

介绍

Elasticsearch(简称 ES) 是一个开源的、分布式的、高度可扩展的搜索和分析引擎

ES 经常与 Logstash(数据收集和处理管道)和 Kibana(数据可视化)一起使用,组成著名的 ELK Stack(现在官方称为 Elastic Stack),能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。

核心区别:

  • 结构化数据(固定的数据模型和格式),例子:关系型数据库(MySQL, Oracle)表中的数据
  • 半结构化数据(具有某种结构,但格式不固定),例子:NoSQL数据库、文件系统
  • 非结构化数据(没有预定义的数据模型或格式),例子:文本文档、图片、音频、视频、PDF

安装

ES的官方地址:https://www.elastic.co/cn/

下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch

7.8版本下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-8-0

目录结构:

  • bin 可执行脚本目录
  • config 配置目录
  • jdk 内置 JDK 目录(可替换)
  • lib 类库
  • logs 日志目录
  • modules 模块目录
  • plugins 插件目录

解压后,进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务 。

注意:9300 端口为 ES集群间组件的通信端口, 9200 端口为浏览器访问的 http协议 RESTful 端口。

打开浏览器,输入地址: http://localhost:9200,有一串json代表安装成功。

yml 复制代码
如果安装失败,可能空间不足,修改 config/jvm.options 配置文件:
# 设置 JVM 初始内存为 1G。此值可以设置与-Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存
# Xms represents the initial size of total heap space
# 设置 JVM 最大可用内存为 1G
# Xmx represents the maximum size of total heap space
-Xms1g
-Xmx1g

数据格式

ES是面向文档型数据库,一条数据在这里就是一个文档。为了方便大家理解,我们将 ES里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比。

ES 里的 Index 可以看做一个库,而 Types 相当于表(7版本后已经删除),Documents 则相当于表的行。

  • 正排索引(文档 -> 包含哪些词),通过文档ID快速获取文档内容
  • 倒排索引(词 -> 出现在哪些文档?),通过关键词快速查找包含它的所有文档

HTTP 基本操作

索引操作

对比关系型数据库,创建索引就等同于创建数据库。

创建索引

http 复制代码
# 创建索引 shopping是索引名,注意:PUT请求具有幂等性
PUT http://localhost:9200/shopping
Content-Type:application/json
# 返回响应:
{
    "acknowledged": true,  //响应结果
    "shards_acknowledged": true,  //分片结果
    "index": "shopping"    //索引名称
}

查询索引

http 复制代码
# 查询索引 shopping是索引名
GET http://localhost:9200/shopping

删除索引

http 复制代码
# 删除索引 shopping是索引名
DELETE http://localhost:9200/shopping

查看所有索引

http 复制代码
# _cat 表示查看的意思, indices 表示索引,相当于Mysql的show tables
GET http://localhost:9200/_cat/indices?v
# 返回响应:
health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   shopping J0WlEhh4R7aDrfIc3AkwWQ   1   1          0            0       208b           208b

-----解释-----
health  当前服务器健康状态: green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status	索引打开、关闭状态
index	索引名
uuid	索引统一编号
pri	    主分片数量
rep	    副本数量
docs.count	   可用文档数量
docs.deleted   文档删除状态(逻辑删除)
store.size	   主分片和副分片整体占空间大小
pri.store.size 主分片占空间大小

文档操作

这里的文档可以类比为关系型数,据库中的表数据,添加的数据格式为 JSON 格式。

文档创建
http 复制代码
# 创建文档, shopping是索引名, 在该索引创建文档 (返回的_id,会随机生成)
POST http://localhost:9200/shopping/_doc
Content-Type:application/json
{
 	"title": "小米",
 	"value": "content",
 	"price": 3999
}
# 返回响应:
{
    "_index": "shopping",  //索引
    "_type": "_doc",       //类型-文档
    "_id": "ANQqsHgBaKNfVnMbhZYU", //唯一标识,可以类比为 MySQL中的主键,随机生成
    "_version": 1,                 //版本
    "result": "created",           //结果,这里的 create 表示创建成功
    "_shards": {
        "total": 2,      
        "successful": 1, 
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}
# 如果想要自定义唯一性标识, 101就是唯一标识
POST http://localhost:9200/shopping/_doc/101
Content-Type:application/json
{
 	"title": "小米2",
 	"value": "content",
 	"price": 3999
}
主键查询 & 全查询
http 复制代码
# 根据主键查询
GET http://localhost:9200/shopping/_doc/101
# 查询该索引下,全部文档
GET http://localhost:9200/shopping/_search
全量修改 & 局部修改 & 删除
http 复制代码
# 全量修改,将原有的数据内容进行覆盖,101就是唯一标识
PUT http://localhost:9200/shopping/_doc/101
Content-Type:application/json
{
  	"title": "小米2-修改",
  	"value": "content-修改",
  	"price": 3999
}
# 局部修改,只修改某一给条数据的局部信息,101就是唯一标识
POST http://localhost:9200/shopping/_update/101
Content-Type:application/json
{
 "doc": {
 	"title": "修改华为"
 }
}
# 删除某一个文档,101就是唯一标识,注意:删除一个文档不会立即从磁盘上移除
DELETE http://localhost:9200/shopping/_doc/101
# 再查看是否删除成功
GET http://localhost:9200/shopping/_doc/101
# 返回响应:foun=false,代表成功
{
    "_index": "shopping",
    "_type": "_doc",
    "_id": "1",
    "found": false
}
# 条件删除文档
POST http://localhost:9200/shopping/_delete_by_query
Content-Type:application/json
{
 "query": {
 	"match": {
 	 	"price":3999
 	}
 }
}
条件查询
http 复制代码
# 条件查询:方式1:查询title=小米
GET http://localhost:9200/shopping/_search?q=title:小米
# 条件查询:方式2:查询title=小米
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
 	"query": {
 		"match": {
 			"title": "小米"
 		}
	 }
}
# 字段匹配查询,在多个字段中查询
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"multi_match": {
 			"query": "小米",
 			"fields": ["title","value"]
 		}
	}
}
# 全查询
#GET http://localhost:9200/shopping/_search
#Content-Type:application/json
{
	"query":{
		"match_all":{}
	}
}
# 查询指定字段
#GET http://localhost:9200/shopping/_search
#Content-Type:application/json
{
	"query":{
		"match_all":{}
	},
	"_source":["title","price"] // 只展示title,其他字段不展示
}
分页查询 & 查询排序
http 复制代码
# 分页查询
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"match_all":{}
	},
	"from":0, //当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size
	"size":2  //每页显示多少条
}
# 查询排序
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"match_all":{}
	},
	"sort":{
		"price":{          // 排序字段
			"order":"desc" // desc 降序,asc 升序
		},
		"title":{          // 排序字段
			"order":"desc" // desc 降序,asc 升序
		}
	}
}
多条件查询 & 范围查询
http 复制代码
# bool组合查询通过:must(必须)、must_not(必须不)、should(应该)进行组合 
# 多条件查询,查询小米,价格为3999元的。(must相当于数据库的&&)
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"bool":{
			"must":[{    // 并且
				"match": {"title":"小米"}
			},{
				"match": {"price":3999}
			}]
		}
	}
}
# 多条件查询,查询小米和华为。(should相当于数据库的||)
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"bool":{
			"should":[{   // 或者
				"match":{"title":"小米"}
			},{
				"match":{"title":"华为"}
			}]
		},
        "filter":{  // 范围查询:价格大于2000元的
            "range":{
                "price":{"gt":2000 }
            }
        }
	}
}
# 范围查询:range 查询允许以下字符
    gt  大于>
    gte 大于等于>=
    lt  小于<
    lte 小于等于<=
全文检索 & 完全匹配 & 高亮查询
http 复制代码
# 全文检索
# 如搜索引擎那样,输入"小华",返回结果带回品牌有小米和华为的数据
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"match":{
			"title" : "小华"
		}
	}
}
# 完全匹配
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"match_phrase":{
			"title" : "为"
		}
	}
}
# 高亮查询,highlight 高亮显示
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"query":{
		"match_phrase":{
			"title" : "为"
		}
	},
    "highlight":{
        "fields":{
            "title":{} //<----高亮这字段
        }
    }
//    "highlight": {
// 		"pre_tags": "<font color='red'>",  //前置标签
//		"post_tags": "</font>",            //后置标签
//		"fields": {                        //需要高亮的字段
// 			"name": {}
// 		}
// 	}
}
聚合查询

聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值max、平均值avg等等。

http 复制代码
# 聚合操作 terms 分组
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"aggs":{             //聚合操作
		"price_group":{  //名称,可以随意起名
			"terms":{    //分组
				"field":"price" //聚合字段
			}
		}
	},
	"size":0   // 不显示全量数据,hits里不再返回数据
}
# 聚合操作 avg 平均值
GET http://localhost:9200/shopping/_search
Content-Type:application/json
{
	"aggs":{          //聚合操作
		"price_avg":{ //名称,随意起名
			"avg":{   //求平均值
				"field":"price"  //聚合字段
			}
		}
	},
    "size":0
}
映射关系

类似于数据库(database)中的表结构(table),创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。

http 复制代码
# 创建映射,还可以通过GET进行查询
PUT http://localhost:9200/user/_mapping
Content-Type:application/json
{
    "properties": {
        "name":{
        	"type": "text", //可分词
        	"index": true   //是否索引,默认为 true,可以用来搜索
        },
        "sex":{
        	"type": "keyword", //不可分词,数据会作为完整字段进行匹配
        	"index": true
        },
        "tel":{
        	"type": "keyword",
        	"index": false   //字段不会被索引,不能用来搜索
        }
    }
}
# 其他映射数据说明
 store:是否将数据进行独立存储,默认为 false
 analyzer:分词器,这里的 ik_max_word 即使用 ik 分词器

JavaAPI-环境准备

可在我的码云ES项目,有JAVA项目连接ES,进行基本API操作。

地址:https://gitee.com/yan418

Elasticsearch环境

集群 Cluster

一个集群就是由一个或多个服务器节点组织在一起,共同持有整个的数据,并一起提供索引和搜索功能。一个 Elasticsearch 集群有一个唯一的名字标识,这个名字默认就是"elasticsearch"。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群。

节点 Node

集群中包含很多服务器, 一个节点就是其中的一个服务器。 作为集群的一部分,它存储数据,参与集群的索引和搜索功能。

例子:节点1存入数据a、数据b;节点2存入数据c、数据d;查询数据c,需要访问节点2。

Windows集群部署

步骤1:部署集群

创建 elasticsearch-cluster 文件夹,分别在该目录下创建node1、node2、node3文件夹,分别安装ES服务;

步骤2:修改配置文件

每个节点的 config/elasticsearch.yml 配置文件

node1节点配置

yml 复制代码
# 节点1-配置信息:
# 集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
# 节点名称,集群内要唯一
node.name: node-1
node.master: true
node.data: true
# ip 地址
network.host: localhost
# http 端口
http.port: 1001
# tcp 监听端口
transport.tcp.port: 9301
# 跨域配置
# action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"

node2节点配置

yml 复制代码
# 节点2-配置信息:
# 集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
# 节点名称,集群内要唯一
node.name: node-2
node.master: true
node.data: true
# ip 地址
network.host: localhost
# http 端口
http.port: 1002
# tcp 监听端口
transport.tcp.port: 9302
# 节点发现其他节点,查询node1节点
discovery.seed_hosts: ["localhost:9301"]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5
# 跨域配置
# action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"

node3节点配置

yml 复制代码
# 节点3-配置信息:
# 集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
# 节点名称,集群内要唯一
node.name: node-3
node.master: true
node.data: true

network.host: localhost
http.port: 1003
transport.tcp.port: 9303

# 候选主节点的地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["localhost:9301", "localhost:9302"]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5

#集群内的可以被选为主节点的节点列表
#cluster.initial_master_nodes: ["node-1", "node-2","node-3"]
# 跨域配置
# action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"

步驟3:启动服务

分别启动每个服务,进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务 。

注意:启动前删除每个节点中的 data 目录中所有内容、和logs目录里日志文件。

步骤4:测试集群

访问机器节点状态:

  1. GET http://127.0.0.1:1001/_cluster/health
  2. GET http://127.0.0.1:1002/_cluster/health
  3. GET http://127.0.0.1:1003/_cluster/health
json 复制代码
# 访问:http://localhost:1001/_cluster/health
# 响应结果:
{
  "cluster_name": "my-application",  
  "status": "green",   // green 所有的主分片和副本分片都正常运行。
					   // yellow:所有的主分片都正常运行,但不是所有的副本分片都正常运行。
                       // red:有主分片没能正常运行。
  "timed_out": false,
  "number_of_nodes": 3,      // 集群中有3个节点
  "number_of_data_nodes": 3, // 集群中有3个数据节点
  "active_primary_shards": 0,
  "active_shards": 0,
  "relocating_shards": 0,
  "initializing_shards": 0,
  "unassigned_shards": 0,
  "delayed_unassigned_shards": 0,
  "number_of_pending_tasks": 0,
  "number_of_in_flight_fetch": 0,
  "task_max_waiting_in_queue_millis": 0,
  "active_shards_percent_as_number": 100
}

Linux集群部署

Elasticsearch 7.8.0下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-8-0

待补充:

Elasticsearch进阶

核心概念

  • 索引(Index):一个索引就是一个拥有几分相似特征的文档的集合,为了提高搜索的性能
  • 类型(Type):默认不再支持自定义索引类型(默认类型为: _doc)
  • 文档(Document):是一条数据,以 JSON格式标识
  • 字段(Field):相当于是数据表的字段,对文档数据根据不同属性进行的分类标识
  • 映射(Mapping):某个字段的数据类型、默认值、分析器、是否被索引等
  • 分片(Shards):一个索引可以存储超出单个节点硬件限制的大量数据,相当于Mysql中的分表
  • 副本(Replicas):避免数据丢失,将数据进行多个备份
  • 分配(Allocation):将分片分配给某个节点的过程,包括分配主分片或者副本。如果是副本,还包含从主分片复制数据的过程。这个过程是由 master 节点完成的。

系统架构

一个运行中的 Elasticsearch 实例称为一个节点,而集群是由一个或者多个拥有相同cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。

当一个节点被选举成为主节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 任何节点都可以成为主节点。

如图:有3个Node节点,Node1是主节点,P0的备份数据在Node2上,P1的备份数据在Node3上,P2的备份数据在Node1上,每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。

相关推荐
Elastic 中国社区官方博客3 小时前
Elasticsearch:Jina Reranker v3
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索·jina
Elastic 中国社区官方博客3 小时前
Elasticsearch:Jina Reader
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索·jina
Elasticsearch3 小时前
JINA AI 与 Elasticsearch 的集成
elasticsearch
Elasticsearch3 小时前
使用 Elastic 中的 OpenTelemetry 为 Nginx 实现端到端分布式追踪的实用指南
elasticsearch
Tancenter4 小时前
Mysql和ElasticsSearch
数据库·mysql·elasticsearch
劉煥平CHN4 小时前
ElasticSearch 小版本 RPM 滚动升级(如 7.14.0 → 7.17.10,无服务中断)
elasticsearch
老陈头聊SEO6 小时前
AI技术赋能SEO关键词优化策略新路径解析
其他·搜索引擎·seo优化
jayaccc14 小时前
Git命令大全:从入门到精通
大数据·git·elasticsearch
论迹17 小时前
【Git】-- Git安装 & 卸载(ubuntu)
git·ubuntu·elasticsearch