Elasticsearch 安装
下载地址:https://www.elastic.co/downloads/past-releases#elasticsearch
这里选择windows版本的
下载完成后解压缩
进入bin
目录
双击elasticsearch.bat
或在cmd中运行
可以看到 9200
和 9300
端口被占用了
9300
端口为 Elasticsearch 集群间组件的通信端口9200
端口为基于 http协议 RESTful 端口用于对外开放的交互端口。
使用浏览器(或者接口测试工具),输入地址:http://localhost:9200
,测试结果
Elasticsearch 数据格式
Elasticsearch 是面向文档的数据库,每一条数据就是一个文档。为了便于理解,可以将 Elasticsearch 层级概念和关系型数据库 MySQL 的层级概念进行一个类比。
ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个type,Elasticsearch 7.X 中, Type 的概念已经被删除了。
Elasticsearch使用
下载安装接口测试工具
这里我使用的是postman
下载地址:https://app.getpostman.com/app/download/win64
这个工具是免费的下载安装就可以,如果提示注册可以跳过或注册一下就可以
基于http操作es
索引
创建索引
对比关系型数据库,创建索引就是创建数据库
在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/hello
查看所有索引
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/_cat/indices?v
请求路径中的_cat
表示查看,indices
表示索引,组合起来就是查看当前 ES
服务器中的所有索引,类似于 MySQL 中的 show tables ,服务器响应结果如下
表头 | 含义 |
---|---|
health | 当前服务器健康状态:green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) |
status | 索引打开、关闭状态 |
index | 索引名 |
uuid | 索引统一编号 |
pri | 主分片数量 |
rep | 副本数量 |
docs.count | 可用文档数量 |
docs.deleted | 文档删除状态(逻辑删除) |
store.size | 主分片和副分片整体占空间大小 |
pri.store.size | 主分片占空间大小 |
查看单个索引
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/hello
请求后,服务器响应结果如下:
"shopping"【索引名】
"aliases"【别名】
"mappings"【映射】
"settings"【设置】
"index"【设置 - 索引】
"creation_date"【设置 - 索引 - 创建时间】
"number_of_shards"【设置 - 索引 - 主分片数量】
"number_of_replicas"【设置 - 索引 - 副分片数量】
"uuid"【设置 - 索引 - 唯一标识】
"version"【设置 - 索引 - 版本】
"created": "7080099"
"provided_name"【设置 - 索引 - 名称】
删除索引
在 Postman 中,向 ES 服务器发 DELETE 请求 :http://127.0.0.1:9200/hello
重新查询
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/hello
文档操作
创建文档
再次创建hello
索引
在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/hello
创建索后,接下来创建文档,并添加数据。
文档可以类比为关系型数据库中表,添加的数据格式为 JSON 格式
在 Postman 中,向 ES 服务器发 POST 请求 ,同时附带请求体:http://127.0.0.1:9200/hello/_doc
请求体
{
"title":"hello es",
"content":"this is my first es doc"
}
"_index"【索引】
"_type"【类型-文档】
"_id"【唯一标识】#可以类比为 MySQL 中的主键,随机生成
"_version"【版本】
"result"【结果】#这里的 create 表示创建成功
"_shards"【分片】
"total"【分片 - 总数】
"successful"【分片 - 成功】
"failed"【分片 - 失败】
"_seq_no": 0,
"_primary_term": 1
上面的数据创建后,由于没有指定数据唯一性标识(ID),默认情况下,ES 服务器会随机
生成一个。
如果想要自定义唯一性标识,需要在创建时指定:http://127.0.0.1:9200/hello/_doc/1001
如果增加数据时明确数据主键,那么请求方式也可用 PUT
使用postman 发送putq请求 http://127.0.0.1:9200/hello/_doc/1002
添加数据
查看文档
查看文档时,需要指明文档的唯一标识,类似于 MySQL 中数据的主键查询
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/hello/_doc/1001
"_index"【索引】
"_type"【文档类型】
"_id"
"_version"
"_seq_no"
"_primary_term":
"found"【查询结果】: true, # true 表示查找到,false 表示未查找到
"_source":【文档源信息】
"title": "hello es 1001",
"content": "this is my second es doc"
如果返回如下错误信息, 是因为在发get请求时 附加了body信息,在postman中body选择none就可以了
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "request [GET /hello/_doc/1001] does not support having a body"
}
],
"type": "illegal_argument_exception",
"reason": "request [GET /hello/_doc/1001] does not support having a body"
},
"status": 400
}
修改文档
和新增文档一样,输入相同的 URL 地址请求,如果请求体变化,会将原有的数据内容覆盖在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/hello/_doc/1001
请求体
{
"title":"hello es update",
"content":"this is my first es doc update"
}
{
"_index"
"_type"
"_id"
"_version"【版本】
"result"【结果】: "updated", # updated 表示数据被更新
"_shards":
"total":
"successful":
"failed": 0
"_seq_no"
"_primary_term"
修改字段
修改数据时,也可以只修改某一给条数据的局部信息
在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/hello/_update/1001
请求体
{
"doc": {
"title":"this is new title"
}
}
根据唯一性标识,查询文档数据,文档数据已经更新
postman 发送get请求 http://127.0.0.1:9200/hello/_doc/1001
删除文档
删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。
在 Postman 中,向 ES 服务器发 DELETE 请求 :http://127.0.0.1:9200/hello/_doc/1001
{
"_index"
"_type"
"_id"
"_version"【版本】 #对数据的操作,都会更新版本
"result"【结果】: "deleted", # deleted 表示数据被标记为删除
"_shards"
"total"
"successful"
"failed"
"_seq_no"
"_primary_term"
再次查询
使用postman get请求http://127.0.0.1:9200/hello/_doc/1001
删除一个并不存在的文档
使用postman delete请求http://127.0.0.1:9200/hello/_doc/1009
{
"_index"
"_type"
"_id"
"_version"
"result"【结果】: "not_found", # not_found 表示未查找到
"_shards":
"total"
"successful"
"failed"
"_seq_no"
"_primary_term"
条件删除文档
一般删除数据都是根据文档的唯一性标识进行删除,实际操作时,也可以根据条件对多条数据进行删除首先分别增加多条数据
增加几条数据用于删除
post请求 http://127.0.0.1:9200/hello/_doc/1010
{
"title":"test1",
"content":"test1",
"like":100
}
post请求 http://127.0.0.1:9200/hello/_doc/1011
{
"title":"test2",
"content":"test2",
"like":102
}
向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/hello/_delete_by_query
{
"query": {
"match": {
"like": 100
}
}
}
{
"took": 935, # 【耗时】
"timed_out": false, #【是否超时】
"total": 1,#【总数】
"deleted": 1,# 【删除数量】
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1.0,
"throttled_until_millis": 0,
"failures": []
}
映射操作
索引库可以类比为数据库中的 database,在数据库中有database后就需要创建table,在es中就是建立index的映射
创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。
创建映射
创建一个新的索引名为article
在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/article
在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/article/_mapping
请求体
{
"properties": {
"title": {
"type": "text",
"index": true
},
"content": {
"type": "text",
"index": true
}
}
}
- type:类型,Elasticsearch 中支持的很多种数据类型下面介绍几个常用的
- String 类型
- text:可分词
- keyword:不可分词,数据会作为完整字段进行匹配
- Numerical 数值类型
- 基本数据类型:long、integer、short、byte、double、float、half_float
- 浮点数的高精度类型:scaled_float
- Date:日期类型
- Array:数组类型
- Object:对象
- String 类型
- index:是否索引,默认为 true,默认情况下所有字段都会被索引。
- true:字段会被索引,可以用来进行搜索
- false:字段不会被索引,不能用来搜索
- store:是否将数据进行独立存储,默认为 false
- 文本会存储在_source 中,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。
- analyzer:分词器,这里的 ik_max_word 即使用 ik 分词器
查看映射
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_mapping
索引映射关联
高级查询
Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询
插入数据 :
# POST /article/_doc/1001
{
"title":"1001",
"content":"1001"
}
# POST /article/_doc/1002
{
"title":"1002",
"content":"1002"
}
# POST /article/_doc/1003
{
"title":"1003",
"content":"1003"
}
# POST /article/_doc/1004
{
"title":"1004",
"content":"1004"
}
# POST /article/_doc/1005
{
"title":"1005",
"content":"1005"
}
查询所有文档
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"match_all": {}
}
}
{
"took": 2,# 查询花费时间,单位毫秒
"timed_out": false, # 是否超时
"_shards": { # 分片信息
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": { # 搜索命中结果
"total": { # 搜索条件匹配的文档总数
"value": 5, # 总命中计数的值
"relation": "eq" # 计数规则 eq 表示计数准确, gte 表示计数不准确
},
"max_score": 1.0, # 匹配度分值
"hits": [ # 命中结果集合
{
"_index": "article",
"_type": "_doc",
"_id": "1001",
"_score": 1.0,
"_source": {
"title": "1001",
"content": "1001"
}
},
{
"_index": "article",
"_type": "_doc",
"_id": "1002",
"_score": 1.0,
"_source": {
"title": "1002",
"content": "1002"
}
},
{
"_index": "article",
"_type": "_doc",
"_id": "1003",
"_score": 1.0,
"_source": {
"title": "1003",
"content": "1003"
}
},
{
"_index": "article",
"_type": "_doc",
"_id": "1004",
"_score": 1.0,
"_source": {
"title": "1004",
"content": "1004"
}
},
{
"_index": "article",
"_type": "_doc",
"_id": "1005",
"_score": 1.0,
"_source": {
"title": "1005",
"content": "1005"
}
}
]
}
}
字段匹配查询
multi_match 与 match 类似,不同的是它可以在多个字段中查询。
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search
{
"query": {
"multi_match": {
"query": "1001",
"fields": [
"title",
"content"
]
}
}
}
关键字精确查询
term 查询,精确的关键词匹配查询,不对查询条件进行分词。
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"terms": {
"title": [
"hello",
"es"
]
}
}
}
指定查询字段
默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在_source 的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加_source 的过滤
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
{
"_source": ["title"],
"query": {
"terms": {
"title": ["hello"]
}
} }
过滤字段
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
{
"_source": {
"includes": [
"title"
]
},
"query": {
"terms": {
"content": [
"hello"
]
}
}
}
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"_source": {
"excludes": [
"content"
]
},
"query": {
"terms": {
"title": [
"hello"
]
}
}
}
组合查询
bool
把各种其它查询通过must
(必须 )、must_not
(必须不)、should
(应该)的方
式进行组合
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "hello"
}
}
],
"must_not": [
{
"match": {
"content": "1001"
}
}
],
"should": [
{
"match": {
"content": "hello es"
}
}
]
}
}
}
范围查询
range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符
操作符 | 说明 |
---|---|
gt | 大于> |
gte | 大于等于>= |
lt | 小于< |
lte | 小于等于<= |
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"range": {
"title": {
"gte": 1001
}
}
}
}
可以看到虽然title是text类型但是依然可以转化为数字类型进行范围查询
模糊查询
返回包含与搜索字词相似的字词的文档。
编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
- 更改字符(box → fox)
- 删除字符(black → lack)
- 插入字符(sic → sick)
- 转置两个相邻字符(act → cat)
为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体
或扩展。然后查询返回每个扩展的完全匹配。
通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"fuzzy": {
"title": {
"value": "hlelo"
}
}
}
}
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"fuzzy": {
"title": {
"value": "hlelo",
"fuzziness": 1
}
}
}
}
单字段排序
sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc升序。
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
多字段排序
假定我们想要结合使用 _id 和 _score 进行查询,并且匹配的结果首先按照年龄排序,然后按照相关性得分排序
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_id": {
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
}
]
}
高亮查询
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。
Elasticsearch 可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。
在使用 match 查询的同时,加上一个 highlight 属性:
- pre_tags:前置标签
- post_tags:后置标签
- fields:需要高亮的字段
- title:这里声明 title 字段需要高亮,后面可以为这个字段设置特有配置,也可以空
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"match": {
"title": "hello"
}
},
"highlight": {
"pre_tags": "<font color='red'>",
"post_tags": "</font>",
"fields": {
"title": {}
}
}
}
分页查询
from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size
size:每页显示多少条
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"query": {
"match_all": {}
},
"from": 0,
"size": 2
}
聚合查询
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值、平均值等等。
对某个字段取最大值 max
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"max_score": {
"max": {
"field": "_score"
}
}
},
"size": 1
}
对某个字段取最小值 min
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"min_score": {
"min": {
"field": "_score"
}
}
},
"size": 1
}
对某个字段求和 sum
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"sum_score": {
"sum": {
"field": "_score"
}
}
},
"size": 1
}
对某个字段取平均值 avg
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"sum_score": {
"sum": {
"field": "_score"
}
}
},
"size": 1
}
对某个字段的值进行去重之后再取总数
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"cardinality_score": {
"cardinality": {
"field": "_score"
}
}
},
"size": 1
}
State 聚合
stats 聚合,对某个字段一次性返回 count,max,min,avg 和 sum 五个指标
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"stats_score": {
"stats": {
"field": "_score"
}
}
},
"size": 1
}
桶聚合查询
桶聚和相当于 sql 中的 group by 语句
terms 聚合,分组统计
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"score_groupby": {
"terms": {
"field": "_score"
}
}
},
"size": 1
}
在 terms 分组下再进行聚合
在 Postman 中,向 ES 服务器发 GET 请求 :http
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/article/_search
请求体
{
"aggs": {
"score_groupby": {
"terms": {
"field": "_score"
},
"aggs": {
"sum_score": {
"sum": {
"field": "_score"
}
}
}
}
},
"size": 1
}
评论区