Skip to content

文档的增删改

文档是什么?

文档(Document) 是索引中的一条数据,可以类比为关系型数据库表里的一行。文档以 JSON 格式存储,每个文档有一个唯一标识 _id。你可以自己指定 _id,也可以交给 ES 自动生成。


写入文档(Index API)

指定 ID:PUT

http
PUT /my_index/_doc/1
{
  "title": "Elasticsearch 入门",
  "author": "张三",
  "year": 2024
}
  • 路径格式:/索引名/_doc/文档id
  • 若该 ID 已存在,则全量替换原文档(版本号会递增)。
  • 返回中的 resultcreatedupdated_version 为当前版本号。

自动 ID:POST

http
POST /my_index/_doc
{
  "title": "Kibana 使用技巧",
  "author": "李四",
  "year": 2024
}

不写路径中的 ID 时,ES 会生成一个随机 _id,返回结果中会包含 "_id": "xxx"

PUT 与 POST 的区别

  • PUT /索引/_doc/id:必须带 ID,表示“放入/替换这个 ID 的文档”。
  • POST /索引/_doc:可不带 ID,表示“新增一条文档”(ES 自动生成 ID);带 ID 时效果与 PUT 类似(会替换)。

读取文档

http
GET /my_index/_doc/1

返回中会包含 _source 字段,即你写入的 JSON 内容。若只想拿 _source 且不要元数据,可使用:

http
GET /my_index/_doc/1/_source

若文档不存在,返回 404。


更新文档

全量替换

再次对同一 ID 执行 PUT,会整篇覆盖原文档(与“写入”相同)。

部分更新:_update

只更新部分字段,使用 POST _update API,body 里用 doc 描述要更新的字段:

http
POST /my_index/_update/1
{
  "doc": {
    "title": "Elasticsearch 从入门到实战",
    "year": 2025
  }
}

未在 doc 中出现的字段保持不变。若文档不存在,可加 "doc_as_upsert": true,则不存在时会新建该文档。

更新时可通过 _version 做乐观锁,避免并发覆盖(在请求中带 if_seq_noif_primary_term,此处不展开)。


删除文档

http
DELETE /my_index/_doc/1

删除后,该文档不会立即从磁盘物理抹除,而是在后续的段合并(segment merge)中被清理。因此删除会释放空间,但可能有短暂延迟。


批量操作(Bulk API)

需要一次性写入、更新或删除多条文档时,使用 Bulk API 可以减少网络往返,提高效率。

请求格式

使用 POST _bulk,Body 是 NDJSON(每行一个 JSON),每两行为一组:

  • 第一行:动作与对象(index/update/delete/create 等 + 索引名、可选 ID 等)。
  • 第二行:仅对 index/create/update 需要,为数据内容(update 时格式略不同)。

示例:批量索引与删除

http
POST _bulk
{"index":{"_index":"my_index","_id":"2"}}
{"title":"Bulk 批量写入","author":"王五","year":2024}
{"index":{"_index":"my_index","_id":"3"}}
{"title":"聚合入门","author":"赵六","year":2024}
{"delete":{"_index":"my_index","_id":"1"}}
  • index:存在则替换,不存在则创建。
  • create:仅当文档不存在时创建,否则报错。
  • delete:不需要第二行。
  • update:第二行可以是 {"doc":{...}} 或带 script 等。

注意

  • 单条失败不会导致整批失败,需查看返回中的 errors 和每条的 error 字段排查。
  • 每行必须是单个 JSON,不能换行;行尾换行符 \n 不能省略。
  • 建议单次 Bulk 不要过大(如几千到几万条视文档大小而定),避免超时或内存压力。