ElasticSearch(一)
是什么?
Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。
业务场景
数字、文本、地理位置、结构化数据、非结构化数据。适用于所有数据类型。全文本搜索.
全文搜索功能
Google,百度类的网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时 候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;
还有常见的项目中应用日 志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。
一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。
进行全文检索需要扫描整个表,如果数据量大的话即使对 SQL 的语法优化,也收效甚微。建立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。
基于以上原因可以分析得出,在一些生产环境中,使用常规的搜索方式,性能是非常差的:
- 搜索的数据对象是大量的非结构化的文本数据。
- 文件记录量达到数十万或数百万个甚至更多.
- 支持大量基于交互式文本的查询。
- 需求非常灵活的全文搜索查询。
- 对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。
- 对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况。
为了解决结构化数据搜索和非结构化数据搜索性能问题,我们就需要专业,健壮,强大的全 文搜索引擎.
这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎。它的工作原理是计算机 索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引
进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程
。
基于RESTful
REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就 是 RESTful。Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之 间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务 器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用 服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。
在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它 向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客 户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。
在 REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目 标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET、POST、 PUT、DELETE,还可能包括 HEAD 和 OPTIONS。简单的理解就是,如果想要访问互联 网上的资源,就必须向资源所在的服务器发出请求,请求体中必须包含资源的网络路径,以 及对资源进行的操作(增删改查)。
在哪下?
软件包下载
Elasticsearch 的官方地址:https://www.elastic.co/cn/
下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
下载压缩包后解压即可, 进入 bin 目录执行 elasticsearch.bat 即可启动.
docker
镜像下载
下载镜像
docker pull elasticsearch:7.4.2
运行镜像
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /usr/local/docker/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /usr/local/docker/elasticsearch/data:/usr/share/elasticsearch/data \
-v /usr/local/docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
elasticsearch.yml
http.host: 0.0.0.0
docker-compose
elasticsearch:
container_name: "elasticsearch"
image: "elasticsearch:7.4.2"
ports:
- "9200:9200"
- "9300:9300"
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS: -Xms512m -Xmx512m"
logging:
driver: "json-file"
options:
max-size: "1g"
volumes:
- /usr/local/docker/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- /usr/local/docker/elasticsearch/data:/usr/share/elasticsearch/data
- /usr/local/docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins
restart: "always"
验证
访问: http://localhost:9200 提示如下信息表明 ElasticSearch 安装运行成功.
注意事项
- Elasticsearch 是使用 java 开发的,且 7.8 版本的 ES 需要 JDK 版本 1.8 以上,默认安装 包带有 jdk 环境,如果系统配置 JAVA_HOME,那么使用系统默认的 JDK,如果没有配 置使用自带的 JDK,一般建议使用系统配置的 JDK。
- 双击启动窗口闪退,通过路径访问追踪错误,如果是“空间不足”,请修改 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
怎么玩?
基本概念
Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。
ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。 这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个 type,Elasticsearch 7.X 中, Type 的概念已经被删除了。
索引操作
基于 postman测试.
创建索引
对比关系型数据库,创建索引就等同于创建数据库
对比关系型数据库,创建索引就等同于创建数据库 在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/shopping
{
"acknowledged"【响应结果】: true, # true 操作成功
"shards_acknowledged"【分片结果】: true, # 分片操作成功
"index"【索引名称】: "shopping"
}
# 注意:创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片
查看所有索引
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/_cat/indices?v
这里请求路径中的_cat 表示查看的意思,indices 表示索引,所以整体含义就是查看当前 ES 服务器中的所有索引,就好像 MySQL 中的 show tables 的感觉,服务器响应结果如下
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open bank bG3U501nTYKIH1kiZ_k30A 1 1 1000 0 414.3kb 414.3kb
green open .kibana_task_manager_1 92geESKMTj2Fz8A759yNSw 1 0 2 0 30.5kb 30.5kb
green open .apm-agent-configuration WKGG17MqRv2ePq4XszZudg 1 0 0 0 283b 283b
green open .kibana_1 SDZLdXbHTHm23Z5oof4RoQ 1 0 8 0 21.9kb 21.9kb
yellow open users s6k-WhMjSVOcA6bc3nfP_Q 1 1 1 0 4.6kb 4.6kb
yellow open shopping 0CQYtSvNQuSelstwmQXDHQ 1 1 0 0 230b 230b
表头 | 含义 |
---|---|
health | 当前服务器健康状态: green(集群完整) yellow(单店正常, 集群不完整) red(单点不正常) |
status | 索引打开, 关闭状态 |
index | 索引名 |
uuid | 索引统一编号 |
pri | 主分片数量 |
rep | 副本数量 |
docs.count | 可用文档数量 |
docs.deleted | 文档删除状态(逻辑删除) |
story.size | 主分片和副分片整体占用空间大小 |
pri.store.size | 主分片占用空间大小 |
查看单个索引
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/shopping
{
"shopping"【索引名】: {
"aliases"【别名】: {},
"mappings"【映射】: {},
"settings"【设置】: {
"index"【设置 - 索引】: {
"creation_date"【设置 - 索引 - 创建时间】: "1614265373911",
"number_of_shards"【设置 - 索引 - 主分片数量】: "1",
"number_of_replicas"【设置 - 索引 - 副分片数量】: "1",
"uuid"【设置 - 索引 - 唯一标识】: "eI5wemRERTumxGCc1bAk2A",
"version"【设置 - 索引 - 版本】: {
"created": "7080099"
},
"provided_name"【设置 - 索引 - 名称】: "shopping"
}
}
}
}
删除索引
在 Postman 中,向 ES 服务器发 DELETE 请求 :http://127.0.0.1:9200/shopping
{
"acknowledged": true
}
再次查询索引,返回索引不存在:
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index [shopping]",
"resource.type": "index_or_alias",
"resource.id": "shopping",
"index_uuid": "_na_",
"index": "shopping"
}
],
"type": "index_not_found_exception",
"reason": "no such index [shopping]",
"resource.type": "index_or_alias",
"resource.id": "shopping",
"index_uuid": "_na_",
"index": "shopping"
},
"status": 404
}
文档操作
创建文档
不带id
索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为 JSON 格式.
在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/shopping/_doc
请求体内容为:
{
"title":"小米12S Ultra",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":6999.00
}
此处发送请求的方式必须为 POST,不能是 PUT,否则会发生错误.
报错的原因分析
因为 ES 是基于 RESTful 的风格实现了请求处理, 而在 RESTful 中, PUT 操作是幂等性的操作, 也就是每次操作返回的结果都是一样的, 而 POST 操作的话是非幂等性的操作. 当我们在不指定 ID 的情况下, 每次添加文档 ES 会自动帮我们生成一个 ID. 这就意味着每次添加返回的是不一样的数据也就是非幂等性的操作, 这种情况下使用 PUT 请求的话违反了 RESTful 操作的风格, 所以报错.
添加成功返回的数据, ES 会自动生成一个id.
{
"_index"【索引】: "shopping",
"_type"【类型-文档】: "_doc",
"_id"【唯一标识】: "Xhsa2ncBlvF_7lxyCE9G", #可以类比为 MySQL 中的主键,随机生成
"_version"【版本】: 1,
"result"【结果】: "created", #这里的 create 表示创建成功
"_shards"【分片】: {
"total"【分片 - 总数】: 2,
"successful"【分片 - 成功】: 1,
"failed"【分片 - 失败】: 0
},
"_seq_no": 0,
"_primary_term": 1
}
自定义id
如果想要自定义唯一性标识,需要在创建时指定:http://127.0.0.1:9200/shopping/_doc/1
{
"_index": "shopping",
"_type": "_doc",
"_id": "1", # 自定义的id
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 6,
"_primary_term": 1
}
查看文档
查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/shopping/_doc/1
{
"_index"【索引】: "shopping",
"_type"【文档类型】: "_doc",
"_id": "1",
"_version": 2,
"_seq_no": 2,
"_primary_term": 2,
"found"【查询结果】: true, # true 表示查找到,false 表示未查找到
"_source"【文档源信息】: {
"title": "华为手机",
"category": "华为",
"images": "http://www.gulixueyuan.com/hw.jpg",
"price": 4999.00
}
}
修改文档
全文档修改
和新增文档一样,输入相同的 URL 地址请求,如果请求体变化,会将原有的数据内容覆盖
在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/shopping/_doc/1
请求内容:
{
"title":"华为手机",
"category":"华为",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4999.00
}
返回内容:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version"【版本】: 2,
"result"【结果】: "updated", # updated 表示数据被更新
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}
修改指定字段
修改数据时,也可以只修改某一给条数据的局部信息
在 Postman 中,向 ES 服务器发 POST 请求 :
http://127.0.0.1:9200/shopping/_update/1
或
http://127.0.0.1:9200/shopping/_doc/1/_update
请求内容:
{
"doc": {
"price":3000.00
}
}
返回内容:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
"_version": 12,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 14,
"_primary_term": 1
}
删除文档
删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。
在 Postman 中,向 ES 服务器发 DELETE 请求 :http://127.0.0.1:9200/shopping/_doc/1
返回内容:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version"【版本】: 4, #对数据的操作,都会更新版本
"result"【结果】: "deleted", # deleted 表示数据被标记为删除
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 2
}
mapping 映射类型
官方描述: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/removal-of-types.html
在 Elasticsearch 7.0.0 或更高版本中创建的索引不再接受映射。在 6.x 中创建的索引将继续像以前一样在 Elasticsearch 6.x 中运行。在 7.0 的 API 中不推荐使用类型,对索引创建、放置映射、获取映射、放置模板、获取模板和获取字段映射 API 进行了重大更改。`default