使用 Elasticsearch REST API 索引和更新文档

使用 REST API 掌握 Elasticsearch 中核心的创建、读取、更新、删除 (CRUD) 操作。本指南详细介绍了索引新文档(带或不带指定 ID)和对现有记录执行细粒度的部分更新所需的精确 HTTP 请求、端点和 JSON 有效载荷。了解用于原子更新、脚本修改和高效批量数据摄取的实用 `curl` 示例。

39 浏览量

使用 Elasticsearch REST API 索引和更新文档

Elasticsearch 是一个功能强大、分布式的搜索和分析引擎,它依赖于结构良好的数据摄取。管理这些数据涉及基本的创建、读取、更新和删除 (CRUD) 操作,主要通过其多功能的 REST API 执行。理解如何正确索引新文档和高效更新现有文档对于维护实时、准确的数据存储至关重要。

本指南将引导您了解用于在 Elasticsearch 集群中索引新记录和修改现有文档的基本 HTTP 方法和 API 端点。我们将重点关注语法、必需的 JSON 负载以及解释响应代码,以确保无缝的数据管理。


先决条件

继续之前,请确保您已:

  • 运行一个活动的 Elasticsearch 集群。
  • 一个能够发出 HTTP 请求的命令行工具(如 curl)或 HTTP 客户端(如 Postman)。
  • 了解您的目标索引名称。

1. 索引新文档

索引是将 JSON 文档存储到 Elasticsearch 索引中的过程。除非显式提供 ID,否则 Elasticsearch 会自动为文档分配一个唯一的 ID。用于索引的主要方法是 PUTPOST 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
}

显示 createdresult 字段确认已添加新文档。

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)定义,紧随其后的是文档源(如果需要)。

批量操作类型: indexcreateupdatedelete

批量请求示例(混合索引和更新):

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"}}

'

在此示例中:

  1. 索引文档 2001
  2. 部分更新文档 1001(降低价格)。
  3. 删除文档 3003

批量响应: 响应将详细说明批次中每个单独操作的成功或失败,使您能够确定哪些文档成功,哪些失败。


关键 API 命令摘要

操作 HTTP 方法 端点模式 效果
索引(自动 ID) POST /{index}/_doc/ 创建具有自动生成 ID 的新文档。
索引/覆盖 PUT /{index}/_doc/{id} 在指定 ID 创建或完全替换文档。
部分更新 POST /{index}/_update/{id} 合并 doc 块中指定的更改。
批量操作 POST /{index}/_bulk 在一个请求中执行多个操作。

掌握这些基本的 REST API 交互为任何 Elasticsearch 应用程序中的动态数据管理提供了基础。