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 文档操作黄金法则
- 创建文档:
- 业务主键 → PUT + 自定义ID
- 日志类数据 → POST + 自动ID
- 更新文档:
- 全量替换 → PUT
- 字段更新 → POST /_update
- 删除文档:
- 物理删除立即释放空间
- 重要数据建议先备份
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]"
}
}
解决方案:
- 重试机制
- 获取最新版本后更新
- 使用乐观锁控制
5.3 批量操作注意事项
- 单个请求不超过100MB
- 避免单个请求包含过多操作(建议1000-5000个)
- 失败处理:检查响应中的errors和item状态
六、总结
通过本文您已掌握:
- ✅ 文档的创建(PUT/POST)
- ✅ 文档的查询(单个/批量)
- ✅ 文档的更新(全量/部分/脚本)
- ✅ 文档的删除
- ✅ 批量操作API的使用
- ✅ Java客户端操作示例
下期预告:《Elasticsearch RESTful API入门:批量操作与事务处理》