ES101系列02 | ElasticSearch基础CRUD

92 阅读4分钟

本篇文章主要介绍 ElasticSearch 中的基础 CRUD 使用实例和 Bulk、MGet、MSearch 等 API 的使用。

基础 CRUD

操作HTTP 方法响应码Source 处理幂等性备注
CreatePUTPOST201(成功)
409(冲突)
必须提供完整文档 Source是(需指定 ID)仅当文档不存在时创建。需指定 ID(PUT)或自动生成(POST)。
GetGET200(存在)
404(不存在)
可指定 _source 过滤返回字段仅用于查询文档,不修改数据。
IndexPUTPOST201(新建)
200(更新)
必须提供完整文档 Source若文档存在则替换(全量更新)。可指定 ID(PUT)或自动生成(POST)。
UpdatePOST(带 _update200(成功)
404(不存在)
提供部分字段或脚本(支持 docscript部分更新。支持 upsert(不存在时插入)。需启用 _source 字段。默认返回更新后的 Source。

Create

Demo1

# Req
# create document 自动生成 _id
POST users/_doc
{
	"user" : "LanLance"
}

# Resp
{
  "_index" : "users",
  "_type" : "_doc",
  "_id" : "64IRqpYBLb6gKsOx04Rm",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

Demo2

# Req
# create document 指定 ID
PUT users/_doc/1?op_type=create
{
    "user" : "LanLance_2"
}

# Resp
{
  "_index" : "users",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

Demo3

# Req
# create document 指定 ID;如果已经存在就报错
PUT users/_create/1
{
    "user" : "LanLance"
}

# Resp
{
  "error" : {
    "root_cause" : [
      {
        "type" : "version_conflict_engine_exception",
        "reason" : "[1]: version conflict, document already exists (current version [1])",
        "index_uuid" : "J6rYdyr6TY-H9asFHjyTwQ",
        "shard" : "0",
        "index" : "users"
      }
    ],
    "type" : "version_conflict_engine_exception",
    "reason" : "[1]: version conflict, document already exists (current version [1])",
    "index_uuid" : "J6rYdyr6TY-H9asFHjyTwQ",
    "shard" : "0",
    "index" : "users"
  },
  "status" : 409
}

Get

Demo1

# Req
# Get 指定 ID
GET users/_doc/1

# Resp
{
  "_index" : "users",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "user" : "LanLance_2"
  }
}

Index & Update

Demo1

# Req
# Update 指定 ID (先删除,在写入)
PUT users/_doc/1
{
	"user" : "LanLance"
}

# Resp
{
  "_index" : "users",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

Demo2

# Req
# Update 在原文档上增加字段
POST users/_update/1/
{
    "doc":{
        "message" : "trying out Elasticsearch"
    }
}

# Resp
{
  "_index" : "users",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

Delete

Demo1

# Req
# Delete 指定 ID
DELETE users/_doc/1

# Resp
{
  "_index" : "users",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 1
}

Bulk、MGet、MSearch

APIHTTP 方法操作类型主要用途响应码幂等性性能优化点
BulkPOST批量增删改(Create/Index/Update/Delete)批量写入或更新数据200(整体成功,可能部分失败)单次请求处理大量操作
mgetGET/POST批量读取文档批量获取多个文档内容200(包含每个文档状态)减少网络请求次数
msearchPOST批量搜索请求批量执行多个搜索查询200(包含每个查询结果)合并多个查询请求,减少延迟

功能与场景对比

特性Bulk APImgetmsearch
核心操作增删改(CRUD)读取文档执行搜索查询
数据量优化单次请求处理数千操作单次请求获取数百文档单次请求合并多个复杂查询
错误处理响应中标记每个操作的 errorstatus响应中标记每个文档的 found 状态每个查询独立返回状态码和结果
适用场景数据迁移、日志流写入批量加载关联数据、初始化页面仪表盘批量拉取数据、跨索引聚合分析
原子性非原子(部分成功需重试)非原子非原子

性能与限制对比

维度Bulk APImgetmsearch
网络开销单次请求处理大量操作(高吞吐)减少多次 GET 请求(中吞吐)合并多个查询(中高吞吐)
内存消耗高(需缓存批量数据)中(文档数量和大小决定)高(复杂查询可能占用内存)
超时风险大数据量可能触发请求超时大文档列表可能超时复杂查询或大数据集可能超时
分片影响写入压力分散到多个分片读取压力分散到多个分片搜索压力分散到多个分片
限制规避分批提交(每批 5-15MB)分批查询(每批 100-1000 文档)控制单个查询复杂度

使用

# bulk
## 执行第1次
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test2", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

## 执行第2次
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test2", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

# mget
GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_id" : "1"
        },
        {
            "_index" : "test",
            "_id" : "2"
        }
    ]
}

## URI 中指定 index
GET /test/_mget
{
    "docs" : [
        {

            "_id" : "1"
        },
        {

            "_id" : "2"
        }
    ]
}

GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_id" : "1",
            "_source" : false
        },
        {
            "_index" : "test",
            "_id" : "2",
            "_source" : ["field3", "field4"]
        },
        {
            "_index" : "test",
            "_id" : "3",
            "_source" : {
                "include": ["user"],
                "exclude": ["user.location"]
            }
        }
    ]
}

清除数据

DELETE users
DELETE test
DELETE test2

写在最后

这是该系列的第二篇,主要讲解 ElasticSearch 基础的 CRUD 操作,可以自己去到 Kibana 的 Dev Tool 实战操作,未来会持续更新该系列,欢迎关注👏🏻。

同时欢迎关注公众号:LanTech指南。不定时分享职场思考、独立开发日志、大厂方法论和后端经验❤️

参考

  1. github.com/onebirdrock…