- 基本概念
- 索引操作
- 文档操作
- 添加(索引)文档:POST和PUT
- 修改文档
- 全量更新
- 增量修改
- 使用
_update
部分更新
- 使用
_update_by_query
更新文档
- 并发场景下修改文档
- 查询文档
- 根据id查询文档
- 条件查询
_search
- REST风格的请求URI,直接将参数带过去
- 封装到request body中,这种方式可以定义更加易读的JSON格式
- 删除文档
- 文档批量操作
- 批量写入
- 批量创建文档 create
- 普通创建或全量替换 index
- 批量删除 delete
- 批量修改 update
- 批量读取:
_mget
_msearch
基本概念
- 索引(Index)
- 一个索引就是一个拥有几分相似特征的文档的集合
- 一个索引由一个名字来标识(必须全部是小写字母的)
- 并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字
- 文档(Document)
- Elasticsearch是面向文档的,文档是所有可搜索数据的最小单位
- 文档会被序列化成JSON格式,保存在Elasticsearch中
- 每个文档都有一个Unique ID
- 可以自己指定ID或者通过Elasticsearch自动生成
- 一篇文档包含了一系列字段,类似数据库表中的一条记录
- JSON文档,格式灵活,不需要预先定义格式
- 元数据,用于标注文档的相关信息
_index
:文档所属的索引名
_type
:文档所属的类型名
_id
:文档唯— ld
_source
:文档的原始Json数据
_version
: 文档的版本号,修改删除操作_version都会自增1
_seq_no
: 和_version
一样,一旦数据发生更改,数据也一直是累计的
- Shard级别严格递增,保证后写入的Doc的
_seq_n
o大于先写入的Doc的_seq_no
_primary_term
:主要是用来恢复数据时处理当多个文档的_seq_no
一样时的冲突,避免Primary Shard上的写入被覆盖。每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term
会递增1
索引操作
- 创建索引(
PUT /索引名称
):索引命名必须小写,不能以下划线开头
# 创建索引
PUT /es_db
# 创建索引时可以设置分片数和副本数
PUT /es_db
{"settings":{
"number_of_shards":3,
"number_of_replicas":2}}
# 修改索引配置
PUT /es_db/_settings
{"index":{"number_of_replicas":1}}
# 查询索引
GET /es_db
# es_db 是否存在
HEAD /es_db
文档操作
- 添加(索引)文档 (
[PUT | POST] /索引名称/[_doc | _create ]/id
)
- POST和PUT都能起到创建/更新的作用
- PUT需要对一个具体的资源进行操作也就是要确定id才能进行更新/创建(指定id)
- 如果id不存在,创建新的文档,否则先删除现有文档,再创建新的文档,版本会增加
- POST是可以针对整个资源集合进行操作的,如果不写id就由ES生成一个唯一id进行创建新文档,如果填了id那就针对这个id的文档进行创建/更新
PUT /es_db
{"settings":{
"index":{"analysis.analyzer.default.type":"ik_max_word"}}}
PUT /es_db/_doc/1
{"name":"张三","sex":1,"age":25,
"address":"广州天河公园",
"remark":"java developer"}
- 修改文档(
[PUT | POST] /索引名称/_doc/id
)
- 全量更新,整个json都会替换
- 如果文档存在,现有文档会被删除,新的文档会被索引
PUT /es_db/_doc/1/
{"name":"张三","sex":1,"age":25}
- 使用
_update
部分更新(POST /索引名称/_update/id
)
- update不会删除原来的文档,而是实现真正的数据更新
- 部分更新:在原有文档上更新
- 文档必须已经存在,更新只会对相应字段做增量修改
POST /es_db/_update/1
{"doc":{"age":28}}
POST /es_db/_update_by_query
{"query":{
"match":{"_id":1}},
"script":{"source":"ctx._source.age=30"}}
- 并发场景下修改文档
_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"}
- 查询文档:
- 根据id查询文档(
GET /索引名称/_doc/id
)
- 条件查询
_search
(GET /索引名称/_doc/_search
)
GET /es_db/_doc/_search
查询前10条文档
- REST风格的请求URI,直接将参数带过去
# 条件查询
GET /es_db/_doc/_search?q=age:28
# 范围查询
GET /es_db/_doc/_search?q=age[25 TO 26]
# 分页查询 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
- 封装到request body中,这种方式可以定义更加易读的JSON格式
GET /es_db/_search
{"query":{"match":{"address":"广州白云"}}}
- 删除文档(
DELETE /索引名称/_doc/id
)
文档批量操作
- 批量操作可以减少网络连接所产生的开销,提升性能
- 支持在一次API调用中,对不同的索引进行操作
- 可以在URI中指定Index,也可以在请求的Payload中进行
- 操作中单条操作失败,并不会影响其他操作
- 返回结果包括了每一条操作执行的结果
- 批量写入:批量对文档进行写操作是通过
_bulk
的API来实现的
- 请求方式:POST
- 请求地址:
_bulk
- 请求参数:通过
_bulk
操作文档,一般至少有两行参数 (或偶数行参数)
- 第一行参数为指定操作的类型及操作的对象 (index,type和id)
- actionName:表示操作类型,主要有create, index, delete和update
- 第二行参数才是操作的数据
POST _bulk
{"actionName":{"_index":"indexName", "_type":"typeName","_id":"id"}}
{"field1":"value1", "field2":"value2"}
POST _bulk
{"create":{"_index":"article", "_type":"_doc", "_id":3}}
{"id":3,"title":"title1","content":"con1","tags":["java", "py"],"create_time":1554015482530}
{"create":{"_index":"article", "_type":"_doc", "_id":4}}
{"id":4,"title":"title2","content":"con2","tags":["java", "py"],"create_time":1554015482530}
- 普通创建或全量替换 index
- 如果原文档不存在,则是创建
- 如果原文档存在,则是替换 (全量修改原文档)
POST _bulk
{"index":{"_index":"article", "_type":"_doc", "_id":3}}
{"id":3,"title":"title3","content":"con3","tags":["java", "py"],"create_time":1554015482530}
{"index":{"_index":"article", "_type":"_doc", "_id":4}}
{"id":4,"title":"title4","content":"con4","tags": "java", "py"],"create_time":1554015482530}
POST _bulk
{"delete":{"_index":"article", "_type":"_doc", "_id":3}}
{"delete":{"_index":"article", "_type":"_doc", "_id":4}}
POST _bulk
{"update":{"_index":"article", "_type":"_doc", "_id":3}}
{"doc":{"title":"ES大法必修内功"}}
{"update":{"_index":"article", "_type":"_doc", "_id":4}}
{"doc":{"create_time":1554018421008}}
POST _bulk
{"create":{"_index":"article", "_type":"_doc", "_id":3}}
{"id":6,"title":"title6","content":"con6","tags":["java", "py"],"create_time":1554015482530}
{"delete":{"_index":"article", "_type":"_doc", "_id":3}}
{"update":{"_index":"article", "_type":"_doc", "_id":4}}
{"doc":{"create_time":1554018421008}}
- 批量读取
- es的批量查询可以使用mget和msearch两种
- 其中mget是需要我们知道它的id,可以指定不同的index,也可以指定返回值source
- msearch可以通过字段查询来进行一个批量的查找
_mget
- 可以通过ID批量获取不同index和type的数据
- 可以通过ID批量获取es_db的数据
# 可以通过ID批量获取不同index和type的数据
GET _mget
{"docs": [
{"_index":"es_db","_id":1},
{"_index":"article","_id":4}]}
# 可以通过ID批量获取es_db的数据
GET /es_db/_mget
{"docs": [{"_id":1},{"_id":4}]}
# 简化
GET /es_db/_mget
{"ids":["1","2"]}
_msearch
- 在
_msearch
中,请求格式和bulk类似
- 查询一条数据需要两个对象,第一个设置index和type,第二个设置查询语句
- 查询语句和search相同
- 如果只是查询一个index,我们可以在url中带上index,这样,如果查该index可以直接用空对象表示
GET /es_db/_msearch
{}
{"query" : {"match_all" : {}}, "from" : 0, "size" : 2}
{"index" : "article"}
{"query" : {"match_all" : {}}}