Elasticsearch RESTful API入门:文档的增删改查完全指南

发布于:2025-07-12 ⋅ 阅读:(31) ⋅ 点赞:(0)

Elasticsearch RESTful API入门:文档的增删改查完全指南

本文是Elasticsearch RESTful API系列第三篇,将手把手教你掌握文档的CRUD操作(创建、读取、更新、删除)

一、文档操作前置知识

1.1 文档基础概念

  • 文档(Document):Elasticsearch中的最小数据单元,采用JSON格式
  • 文档元数据
    • _index:所属索引
    • _id:文档唯一标识
    • _version:版本号(用于乐观锁控制)
    • _source:原始JSON数据

1.2 唯一标识_id详解

生成方式 特点 适用场景
自定义ID 开发者指定唯一标识 有业务主键的数据
自动生成ID Elasticsearch生成UUID 日志类无主键数据

二、文档CRUD操作详解

2.1 创建文档(Create)

方式1:指定文档ID
PUT /products/_doc/1
{
  "name": "iPhone 13",
  "price": 6799.00,
  "description": "苹果旗舰手机",
  "category": "手机",
  "stock": 100,
  "tags": ["智能手机", "iOS"]
}
// 响应结果
{
  "_index": "products",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}
方式2:自动生成文档ID
POST /products/_doc/
{
  "name": "华为Mate 50",
  "price": 5999.00,
  "description": "华为旗舰手机",
  "category": "手机",
  "stock": 80
}
// 响应中会包含自动生成的_id
{
  "_id": "x5Q2sYkB5R7Qb3zJZQjH", 
  ... // 其他元数据
}

2.2 查询文档(Read)

查询单个文档
GET /products/_doc/1
// 响应结果
{
  "_index": "products",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "name": "iPhone 13",
    "price": 6799.00,
    "description": "苹果旗舰手机",
    "category": "手机",
    "stock": 100,
    "tags": ["智能手机", "iOS"]
  }
}
查询多个文档(mget)
GET /_mget
{
  "docs": [
    {
      "_index": "products",
      "_id": "1"
    },
    {
      "_index": "products",
      "_id": "x5Q2sYkB5R7Qb3zJZQjH"
    }
  ]
}

2.3 更新文档(Update)

全量更新(直接覆盖)
PUT /products/_doc/1
{
  "name": "iPhone 13 Pro",
  "price": 7999.00,
  "description": "苹果旗舰手机",
  "category": "手机",
  "stock": 50
}
// 注意:全量更新会覆盖原文档所有字段!
部分更新(使用_update API)
POST /products/_update/1
{
  "doc": {
    "price": 7399.00,  // 仅更新价格
    "stock": 30         // 更新库存
  }
}
// 响应结果
{
  "_index": "products",
  "_id": "1",
  "_version": 2,        // 版本号增加
  "result": "updated",
  ... // 其他元数据
}
脚本更新(库存减一)
POST /products/_update/1
{
  "script": {
    "source": "ctx._source.stock -= params.quantity",
    "lang": "painless",
    "params": {
      "quantity": 1
    }
  }
}

2.4 删除文档(Delete)

DELETE /products/_doc/1
// 响应结果
{
  "_index": "products",
  "_id": "1",
  "_version": 3,
  "result": "deleted",
  ... // 其他元数据
}
// 查询已删除文档
GET /products/_doc/1
// 返回结果
{
  "found": false
}

三、批量操作(Bulk API)

3.1 批量操作请求格式

{ 操作类型 }
{ 数据体 }
{ 操作类型 }
{ 数据体 }
...

3.2 批量操作示例

POST /_bulk
{ "index" : { "_index" : "products", "_id" : "2" } }
{ "name": "小米12", "price": 3999, "category": "手机" }
{ "update" : { "_index" : "products", "_id" : "1" } }
{ "doc" : { "price": 6999 } }
{ "delete" : { "_index" : "products", "_id" : "x5Q2sYkB5R7Qb3zJZQjH" } }

3.3 批量操作响应解析

{
  "took": 30,
  "errors": false,
  "items": [
    {
      "index": {
        "_index": "products",
        "_id": "2",
        "status": 201,
        ... // 其他元数据
      }
    },
    {
      "update": {
        "_index": "products",
        "_id": "1",
        "status": 200,
        ... // 其他元数据
      }
    },
    {
      "delete": {
        "_index": "products",
        "_id": "x5Q2sYkB5R7Qb3zJZQjH",
        "status": 200,
        ... // 其他元数据
      }
    }
  ]
}

四、Java客户端操作文档

import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
public class DocumentCRUD {
    private final RestHighLevelClient client;
    public DocumentCRUD(RestHighLevelClient client) {
        this.client = client;
    }
    // 创建文档(指定ID)
    public IndexResponse createDocument(String index, String id, String json) throws Exception {
        IndexRequest request = new IndexRequest(index)
                .id(id)
                .source(json, XContentType.JSON);
        return client.index(request, RequestOptions.DEFAULT);
    }
    // 查询文档
    public GetResponse getDocument(String index, String id) throws Exception {
        GetRequest request = new GetRequest(index, id);
        return client.get(request, RequestOptions.DEFAULT);
    }
    // 更新文档(部分更新)
    public UpdateResponse updateDocument(String index, String id, String json) throws Exception {
        UpdateRequest request = new UpdateRequest(index, id)
                .doc(json, XContentType.JSON);
        return client.update(request, RequestOptions.DEFAULT);
    }
    // 删除文档
    public DeleteResponse deleteDocument(String index, String id) throws Exception {
        DeleteRequest request = new DeleteRequest(index, id);
        return client.delete(request, RequestOptions.DEFAULT);
    }
}

五、最佳实践与常见问题

5.1 文档操作黄金法则

  1. 创建文档
    • 业务主键 → PUT + 自定义ID
    • 日志类数据 → POST + 自动ID
  2. 更新文档
    • 全量替换 → PUT
    • 字段更新 → POST /_update
  3. 删除文档
    • 物理删除立即释放空间
    • 重要数据建议先备份

5.2 版本冲突解决

// 更新时指定版本号
PUT /products/_doc/1?version=2&version_type=external
{
  ... // 文档数据
}
// 错误响应
{
  "error": {
    "type": "version_conflict_engine_exception",
    "reason": "[1]: version conflict, current version [2] is different than the one provided [1]"
  }
}

解决方案

  1. 重试机制
  2. 获取最新版本后更新
  3. 使用乐观锁控制

5.3 批量操作注意事项

  1. 单个请求不超过100MB
  2. 避免单个请求包含过多操作(建议1000-5000个)
  3. 失败处理:检查响应中的errors和item状态

六、总结

通过本文您已掌握:

  • ✅ 文档的创建(PUT/POST)
  • ✅ 文档的查询(单个/批量)
  • ✅ 文档的更新(全量/部分/脚本)
  • ✅ 文档的删除
  • ✅ 批量操作API的使用
  • ✅ Java客户端操作示例

下期预告:《Elasticsearch RESTful API入门:批量操作与事务处理》


网站公告

今日签到

点亮在社区的每一天
去签到