使用 Elasticsearch REST API 索引和更新文档
Elasticsearch 是一个功能强大、分布式的搜索和分析引擎,它依赖于结构良好的数据摄取。管理这些数据涉及基本的创建、读取、更新和删除 (CRUD) 操作,主要通过其多功能的 REST API 执行。理解如何正确索引新文档和高效更新现有文档对于维护实时、准确的数据存储至关重要。
本指南将引导您了解用于在 Elasticsearch 集群中索引新记录和修改现有文档的基本 HTTP 方法和 API 端点。我们将重点关注语法、必需的 JSON 负载以及解释响应代码,以确保无缝的数据管理。
先决条件
继续之前,请确保您已:
- 运行一个活动的 Elasticsearch 集群。
- 一个能够发出 HTTP 请求的命令行工具(如
curl)或 HTTP 客户端(如 Postman)。 - 了解您的目标索引名称。
1. 索引新文档
索引是将 JSON 文档存储到 Elasticsearch 索引中的过程。除非显式提供 ID,否则 Elasticsearch 会自动为文档分配一个唯一的 ID。用于索引的主要方法是 PUT 或 POST HTTP 方法。
1.1 使用自动 ID 索引 (POST)
当您使用 POST 请求到索引端点时,Elasticsearch 会为您生成一个唯一的文档 ID。这通常是内部管理 ID 的初始数据摄取的首选方法。
端点: POST /{index_name}/_doc/
请求示例(使用 curl):
curl -X POST "localhost:9200/products/_doc/" -H 'Content-Type: application/json' -d'
{
"name": "Wireless Mouse X1",
"price": 25.99,
"in_stock": true
}
'
成功响应片段:
{
"_index": "products",
"_id": "c7BwJ3gBpV4wT-eH_aY1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
显示 created 的 result 字段确认已添加新文档。
1.2 使用特定 ID 索引 (PUT)
如果您的源系统为文档提供了唯一的标识符,您应该使用 PUT 方法指向特定 ID。如果具有该 ID 的文档已存在,PUT 将覆盖整个文档。
端点: PUT /{index_name}/_doc/{document_id}
请求示例: 索引 ID 为 1001 的文档。
curl -X PUT "localhost:9200/products/_doc/1001" -H 'Content-Type: application/json' -d'
{
"name": "Mechanical Keyboard K90",
"price": 129.99,
"in_stock": true
}
'
成功响应片段:
{
"_index": "products",
"_id": "1001",
"_version": 1,
"result": "created",
"_shards": { ... }
}
关于覆盖的提示: 如果您再次运行完全相同的
PUT请求并使用相同的 ID,result将变为updated,并且_version号将递增。
2. 更新现有文档
更新文档不同于覆盖。当您只想更改现有文档中的特定字段而不影响未更改的字段时,您可以使用 _update 端点,通常使用 POST 方法。
2.1 使用 _update 进行部分更新
_update API 对于原子更新至关重要。它需要在负载中包含一个 doc 块,其中仅包含您希望修改的字段。Elasticsearch 会检索文档,合并更改,然后重新索引它。
端点: POST /{index_name}/_update/{document_id}
示例场景: 我们想将产品 ID 1001 的价格从 129.99 美元更新到 119.99 美元,并将其标记为缺货。
curl -X POST "localhost:9200/products/_update/1001" -H 'Content-Type: application/json' -d'
{
"doc": {
"price": 119.99,
"in_stock": false
}
}
'
成功响应片段:
{
"_index": "products",
"_id": "1001",
"_version": 2,
"result": "updated",
"_shards": { ... }
}
请注意,_version 已从 1 递增到 2,反映了修改。
2.2 使用脚本更新
对于更复杂、条件性或数学性的更新,Elasticsearch 在 _update API 中支持Painless 脚本。这允许您执行诸如递增计数器或根据其当前值设置字段之类的操作。
示例场景: 为文档 ID 1001 增加 5 个库存计数。
curl -X POST "localhost:9200/products/_update/1001" -H 'Content-Type: application/json' -d'
{
"script": {
"source": "ctx._source.stock += params.count",
"params": {
"count": 5
}
}
}
'
关键脚本概念: ctx._source 指的是当前文档源。
关于脚本的警告: 虽然脚本功能强大,但复杂的脚本可能会影响性能。尽可能使用简单的字段更新 (
doc),因为它们通常更快、更安全。
3. 批量索引和更新
对于大量数据操作,为每个文档发送单个请求效率低下。Elasticsearch 提供了 _bulk API 来在单个请求中处理多个索引、更新或删除操作。
3.1 批量请求的结构
批量请求使用特定的、换行符分隔的 JSON (NDJSON) 格式。每个操作由元数据行(指定操作、索引和可选 ID)定义,紧随其后的是文档源(如果需要)。
批量操作类型: index、create、update、delete。
批量请求示例(混合索引和更新):
curl -X POST "localhost:9200/products/_bulk" -H 'Content-Type: application/x-ndjson' -d'
{"index": {"_id": "2001"}}
{"name": "USB-C Hub", "price": 45.00, "in_stock": true}
{"update": {"_id": "1001"}}
{"doc": {"price": 115.00}}
{"delete": {"_id": "3003"}}
'
在此示例中:
- 索引文档
2001。 - 部分更新文档
1001(降低价格)。 - 删除文档
3003。
批量响应: 响应将详细说明批次中每个单独操作的成功或失败,使您能够确定哪些文档成功,哪些失败。
关键 API 命令摘要
| 操作 | HTTP 方法 | 端点模式 | 效果 |
|---|---|---|---|
| 索引(自动 ID) | POST |
/{index}/_doc/ |
创建具有自动生成 ID 的新文档。 |
| 索引/覆盖 | PUT |
/{index}/_doc/{id} |
在指定 ID 创建或完全替换文档。 |
| 部分更新 | POST |
/{index}/_update/{id} |
合并 doc 块中指定的更改。 |
| 批量操作 | POST |
/{index}/_bulk |
在一个请求中执行多个操作。 |
掌握这些基本的 REST API 交互为任何 Elasticsearch 应用程序中的动态数据管理提供了基础。