Elasticsearch应用(三)
1.核心概念介绍
注意:类型(Type)
6.0之前的版本有Type概念,type相当于关系型数据库的表,ES官方将在ES9版本中彻底删除Type。7里面Type为ES默认的类型_doc
2.Cat API
介绍
ES提供了相关的Cat API用来检查ES的各种信息
API
/_cat/allocation #查看单节点的shard分配整体情况
/_cat/shards #查看各shard的详细情况
/_cat/shards/{index} #查看指定分片的详细情况
/_cat/master #查看master节点信息
/_cat/nodes #查看所有节点信息
/_cat/indices #查看集群中所有index的详细信息
/_cat/indices/{index} #查看集群中指定index的详细信息
/_cat/segments #查看各index的segment详细信息,包括segment名, 所属shard, 内存
(磁盘)占用大小, 是否刷盘
/_cat/segments/{index}#查看指定index的segment详细信息
/_cat/count #查看当前集群的doc数量
/_cat/count/{index} #查看指定索引的doc数量
/_cat/recovery #查看集群内每个shard的recovery过程.调整replica。
/_cat/recovery/{index}#查看指定索引shard的recovery过程
/_cat/health #查看集群当前状态:红、黄、绿
/_cat/pending_tasks #查看当前集群的pending task
/_cat/aliases #查看集群中所有alias信息,路由配置等
/_cat/aliases/{alias} #查看指定索引的alias信息
/_cat/thread_pool #查看集群各节点内部不同类型的threadpool的统计信息,
/_cat/plugins #查看集群各个节点上的plugin信息
/_cat/fielddata #查看当前集群各个节点的fielddata内存使用情况
/_cat/fielddata/{fields} #查看指定field的内存使用情况,里面传field属性对应的
值
/_cat/nodeattrs #查看单节点的自定义属性
/_cat/repositories #输出集群中注册快照存储库
/_cat/templates #输出当前正在存在的模板信息
3.索引基础
介绍
索引是文档的容器,是一类文档的结合
索引名命名规则
- 仅小写
- 不能包括\,/,*,?,",<,>,|,``(空格字符), ,,#
- 7.0之前的索引可能包含冒号(:),但已弃用,并且在7.0+中不支持
- 不能以这些开始 -,_,+
- 不能为.或…
- 不能超过255个字节(请注意它是字节,因此多字节字符将更快地计入255个限制)
- 不建议使用以.开头的名称,但隐藏索引和由插件管理的内部索引除外
基础API
增加API
您可以使用create index API将新索引添加到Elasticsearch集群。创建索引时,可以指定以下内容:
- 索引设置
- 索引中字段的映射
- 索引别名
# 创建索引
PUT /es_db# 创建索引时可以设置分片数和副本数
PUT /es_db
{"settings" : {"number_of_shards" : 3,"number_of_replicas" : 2}
}
查询API
# 查询索引
GET /es_db# es_db是否存在
# 注意:该参数不能区分索引名和别名,如果别名存才则返回200
HEAD /es_db# 检索集群中所有索引的信息
GET /_all
删除API
- 您不能使用别名删除索引
- 要删除所有索引,请使用_all或*
- 要禁止使用_all或通配符表达式删除索引,请将action.destructive_requires_name群集设置更改为true
delete /es_db
关于索引修改
索引是不允许修改的,因为索引创建完成后,它的数据结构也就是Mapping都已经定义好了,ES会基于这些Mapping来创建倒排索引,如果修改一个字段会导致原有的倒排索引整个失效,所以ES是禁止修改索引的,虽然ES不允许修改原有的字段但是允许添加新的,语法如下:
PUT /[索引名]/_mapping
{"properties":{"新字段名":{"type":"integer"}}
}
4.文档基础
介绍
文档就是一个JSON数据,每个文档都有一个Unique ID,可以自己指定ID或者通过Elasticsearch自动生成
JSON文档,格式灵活,不需要预先定义格式,字段的类型可以指定或者通过Elasticsearch自动推算,支持数组/支持嵌套
文档元数据
- _index:文档所属的索引名
- _type:文档所属的类型名
- _id:文档唯—ld
- _source: 文档的原始Json数据
- _version: 文档的版本号,修改删除操作_version都会自增1
- _seq_no: 和_version一样,一旦数据发生更改,数据也一直是累计的。Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no
- _primary_term: _primary_term主要是用来恢复数据时处理当多个文档的_seq_no一样时的冲突,避免Primary Shard上的写入被覆盖。每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1
文档删除和修改原理说明
- Elasticsearch执行删除操作时,ES先标记文档为deleted状态,而不是直接物理删除。当ES存储空间不足或工作空闲时,才会执行物理删除操作
- Elasticsearch执行修改操作时,ES不会真的修改Document中的数据,而是标记ES中原有的文档为deleted状态,再创建一个新的文档来存储数据
基础API
增加API
# 如果指定的索引不存在会自动创建# 添加文档并指定id,PUT请求id为必填,使用_doc创建文档如果指定id文档已存在会覆盖
PUT /[index]/_doc/[_id]
{请求体
}# 添加文档不指定id,使用POST请求会自动生成id,使用_doc创建文档如果指定id文档已存在会覆盖
POST /[index]/_doc/
{请求体
}# 添加文档并指定id,使用_create创建文档必须保证文档id不重复否则报错
PUT /[index]/_create/[_id]
{请求体
}# 添加文档并指定id,使用_create创建文档必须保证文档id不重复否则报错
POST /[index]/_create/[_id]
{请求体
}
删除API
# 删除指点id的文档
DELETE /[index]/_doc/[_id]# 根据查询API进行删除
POST /[index]/_delete_by_query
{"query": { "match": {"message": "some message"}}
}
修改API
# 覆盖式修改文档,会覆盖原本id的文档
PUT /[index]/_doc/[_id]
{请求体
}# 局部修改文档,更新部分文档或覆盖式更新
POST /[index]/_update/[_id]
{请求体
}# 批量更新符合某个查询条件的文档
POST /es_db/_update_by_query
{"query": {"match": {"_id": 1}},"script": {"source": "ctx._source.age = 30"}
}# 脚本更新
# es可以内置脚本执行复杂操作。例如painless脚本
# 注意:groovy脚本在es6以后就不支持了。原因是耗内存,不安全远程注入漏洞
post /[索引名]/_doc/[文档id]/_update
{"script":"ctx._source.字段+=1"
}
查询文档
# 要搜索的索引名称的逗号分隔列表或使用_all搜索所有索引# 查询指定id的文档,当然这是最简单的方式,后面会详解整个文档查询
GET /es_db/_doc/1
并发场景下修改文档
_seq_no和_primary_term是对_version的优化,7.X版本的ES默认使用这种方式控制版本,所以当在高并发环境下使用乐观锁机制修改文档时,要带上当前文档的_seq_no和_primary_term进行更新
POST /es_db/_doc/2?if_seq_no=21&if_primary_term=6
{"name": "李四xxx"
}
如果版本号不对,会抛出版本冲突异常,如下图:
5.文档批量操作
要求
bulk 对 JSON串 有着严格的要求。每个JSON串不能换行 ,只能放在同一行,同时, 相邻的JSON串之间必须要有换行 (Linux下是\n;Window下是\r\n)。bulk的每个操作必须要一对JSON串(delete语法除外)
action要求
行为 | 解释 |
---|---|
create | 如果文档不存在就创建,但如果文档存在就返回错误 包含 。POSt和PUT 两种操作 |
index | 如果文档不存在就创建,如果文档存在就更新,版本_version 会加1 |
update | 更新一个文档,如果文档不存在就返回错误 |
delete | 删除一个文档,如果要删除的文档id不存在,就返回错误 |
最大处理数据量
Bulk会把将要处理的数据载入内存中,所以数据量是有限制的,最佳的数据量不是一个确定的数值,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。
一般建议是1000-5000个文档,大小建议是5-15M,默认不能超过100M
优点
- 支持在一次API调用中,对不同的索引进行操作
- 可以在URI中指定Index,也可以在请求的Payload中进行
- 操作中单条操作失败,并不会影响其他操作
- 返回结果包括了每一条操作执行的结果
批量API
混合处理
# bulk批量的混合操作,一般不推荐这种使用,项目中也用的极少PUT /_bulk
{ "create" : { "_index" : "ad", "_id" : "6" }}
{ "doc" : {"name" : "bulk"}}
{ "index" : { "_index" : "ad", "_id" : "6" }}
{ "doc" : {"name" : "bulk"}}
{ "delete":{ "_index" : "ad", "_id" : "1"}}
{ "update":{ "_index" : "ad", "_id" : "3"}}
{ "doc" : {"name" : "huawei p20"}}
批量增加API
POST /example/_bulk
{"index": {"_id": 1}}
{"id":1, "name":"admin", "counter":10, "tags":["red", "black"]}
{"index": {"_id": 2}}
{"id":2, "name":"张三", "counter":20, "tags":["green", "purple"]}
{"index": {"_id": 3}}
{"id":3, "name":"李四", "counter":30, "tags":["red", "blue"]}
{"index": {"_id": 4}}
{"id":4, "name":"tom", "counter":40, "tags":["orange"]}
批量修改API
# 批量修改
POST /example/_bulk
{"update": {"_id": 1}}
{"doc": {"id":1, "name": "admin-02", "counter":11}}
{"update": {"_id": 2}}
{"script":{"lang":"painless","source":"ctx._source.counter += params.num","params":
{"num":2}}}
{"update":{"_id": 3}}
{"doc": {"name": "test3333name", "counter": 999}}
{"update":{"_id": 4}}
{"doc": {"name": "test444name", "counter": 888}, "doc_as_upsert" : true}
批量删除API
# 批量删除
POST /example/_bulk
{"delete": {"_id": 1}}
{"delete": {"_id": 2}}
{"delete": {"_id": 3}}
{"delete": {"_id": 4}}
批量读取之mget
es的批量查询可以使用mget和msearch两种。其中mget是需要我们知道它的
id,可以指定不同的index,也可以指定返回值source。msearch可以通过字段
查询来进行一个批量的查找
# 通过ID批量获取不同index的数据
GET _mget"docs": [{"_index": "example","_type": "docs","_id": "1"},{"_index": "example","_type": "docs","_id": "2"},{"_index": "example_test","_type": "docs","_id": "1"},{"_index": "example_test","_type": "docs","_id": "2"}]# 通过ID批量获取相同index的数据
GET example/docs/_mget
{"docs": [{"_id": "1"},{"_id": "2"},{"_id": "3"}]
}
批量读取之msearch
在_msearch中,请求格式和bulk类似。查询一条数据需要两个对象,第一个设置index和
type,第二个设置查询语句。查询语句和search相同。如果只是查询一个index,我们可以
在url中带上index,这样,如果查该index可以直接用空对象表示
- 严格按照格式组装数据,一条语句一行,最后必须以换行符(\n)结尾
- header和body是成对出现,即使header无内容也要保留“{}”并与换行结束
# 请求格式(JSON)
GET/<indexName>[/<typeName>]/_msearch
{}\n
body\n
{}\n
body\n# 指定index
POST /my_test1/_msearch
{}
{"query":{"match_all":{}}}
{}
{"query":{"match":{"name":"张三"}}}# 多个index
POST /_msearch
{"index":"my_test1"}
{"query":{"match_all":{}}}
{"index":"my_test2"}
{"query":{"match":{"name":"赵六"}}}
6.Rest风格查询
ES的两种查询方式
- REST风格的请求URI,直接将参数带过去
- 封装到request body中,这种方式可以定义更加易读的JSON格式,也叫DSL查询
示例
#通过URI搜索,使用“q”指定查询字符串,“query string syntax” KV键值对# 条件查询, 如要查询age等于28岁的 _search?q=*:***
GET /es_db/_doc/_search?q=age:28# 范围查询, 如要查询age在25至26岁之间的 _search?q=***[** TO **] 注意: TO 必
须为大写
GET /es_db/_doc/_search?q=age[25 TO 26]#查询年龄小于等于28岁的 :<=
GET /es_db/_doc/_search?q=age:<=28# 查询年龄大于28前的 :>
GET /es_db/_doc/_search?q=age:>28# 分页查询 from=*&size=*
GET /es_db/_doc/_search?q=age[25 TO 26]&from=0&size=1# 对查询结果只输出某些字段 _source=字段,字段
GET /es_db/_doc/_search?_source=name,age# 对查询结果排序 sort=字段:desc/asc
GET /es_db/_doc/_search?sort=age:desc