用途
该技能用于将本地数据文件批量加载到 Elasticsearch 索引中。整体流程为:将文件转换为 bulk NDJSON,在字段类型重要时创建带正确映射的索引,批量索引文档,并验证加载结果。
环境配置
该技能通过 elastic CLI 执行 Elasticsearch 操作。如果未安装 elastic CLI,需告知用户其用途。不要猜测凭据、直接调用 HTTP API 或尝试其他绕过方式。文档中使用 HTTP 简写形式描述操作(如 GET /、GET /_cat/indices、POST /_query),文末的 Operations 表将每个简写映射到对应的 elastic CLI 命令,应始终使用 CLI 而非直接调用 HTTP API。
范围
该技能覆盖通过 POST /_bulk 实现文件到索引的加载。不使用 Logstash、Filebeat、Elastic Agent、Node.js ingest 工具或其他边车管道。在已有索引之间复制文档应使用索引到索引的 reindex,而非重新解析源文件。
支持的源文件形态:
- CSV(带表头行):将表头解析为字段名,每行数据输出一条 action 行加一个 JSON 对象。
- JSON 数组文件([{"a":1},{"a":2}]):拆分为每文档一行,切勿将原始数组作为单个文档批量加载。
- NDJSON / JSON Lines(每行一个 JSON 对象):如缺少 action 行可选择补上,否则可直接用于 bulk。
Parquet、Arrow 及其他二进制列式格式不在范围内,除非用户先将其转换为 CSV 或 JSON。
处理流程
- 确认连接。调用 GET /。若失败,停止并先解决 CLI 配置,再读取文件或修改集群状态。
- 检查源文件并分类其形态:CSV(首行为逗号分隔表头,后续为记录,统计数据行数,不含表头);JSON 数组(文件以 [ 开头,包含对象数组,统计数组元素数,每个元素成为一个索引文档);NDJSON(每行一个 JSON 值,可能交替 action 元数据与文档源)。绝对不要将原始 CSV 文本或原始 JSON 数组正文发送到 POST /_bulk。
- 选择目标索引名称。使用用户提供的名称,或基于文件名提出小写名称。索引名必须小写,不能包含空格或 /,不应以 -、_ 或 + 开头。
- 判断是否需要显式映射。若索引可能已存在,调用 GET /{index}/_mapping。当 CSV 列包含需要作为类型化字段查询的数字、日期或布尔值,或用户要求可用的列类型或便于聚合的字段,或此前的加载将所有内容索引为 text/keyword 字符串而需要修正时,在批量加载前创建显式映射。若所有字段都可以保持字符串形式且用户未指定类型,首次批量导入时的动态映射可能足够,但除非用户明确接受全字符串类型,否则对 CSV 优先使用显式映射。
- 需要时创建索引。当步骤 4 需要显式类型(或索引不存在)时,在批量加载前调用 PUT /{index} 并附带 mappings 块。不要依赖动态映射从 CSV 字符串单元格推断 long、date 或 boolean。
- 将文件转换为 bulk NDJSON。写入临时 NDJSON 文件,每个文档占两行:第一行为 action 元数据(如 {"index":{"_index":"<index>"}},仅当用户要求稳定 ID 时才添加 "_id");第二行为类型正确的文档 JSON(数字为 JSON 数字,布尔为 true/false,日期为 ISO-8601 字符串)。CSV 需将表头映射为 JSON 字段名并将单元格值转换为匹配映射的 JSON 类型;JSON 数组需遍历每个元素并输出 action 行加对象行。
- 批量索引文档。调用 POST /_bulk 提交步骤 6 生成的 NDJSON 文件。检查响应:如果 errors 为 true,读取逐项错误对象,修复映射或文档问题,并在修复后重试失败项。不要仅凭退出码为零就假定成功。
- 验证结果。始终确认加载结果,不要仅凭文件检查报告数量。调用 GET /{index}/_count 与步骤 2 中预期的行/元素数比较。当类型化列重要时,调用 GET /{index}/_mapping 确认字段类型(如 age 为 long/integer,日期为 date,布尔为 boolean,而非 text)。报告验证后的文档数及确认的字段类型。
准则
- 仅使用 bulk:所有文件加载都通过 POST /_bulk 与 NDJSON action 行完成,而不是对批量文件使用单文档 PUT 循环,不是用 ingest 管道替代客户端 CSV 解析,也不是提交未处理的源文件。
- JSON 数组必须拆分:将四元素数组作为一个文档批量加载只会得到数量 1;正确加载应得到数量 4。
- CSV 表头即模式:首个 CSV 行命名字段,其余每行一个文档。一个表头加五行数据在导入后应报告数量 5。
- 类型转换在文档 JSON 中进行:CSV 单元格以字符串到达;当映射声明 long、date 或 boolean 时,需在 bulk 正文中输出 JSON 数字、ISO 日期字符串和布尔字面量,不要依赖 Elasticsearch 在动态映射选择 text 后从带引号的 CSV 字符串推断类型。
- 对类型化 CSV 优先使用显式映射:先用 PUT /{index} 创建索引可防止静默的全 text 索引,从而避免破坏范围查询和聚合。
- 幂等重载:向已有索引重新加载时,删除数据前先询问用户。重复的 bulk index action 会追加新文档,除非指定了 _id。
示例
带类型化列的 CSV:源 users.csv(表头加 5 行数据)。使用显式类型创建索引,将行转换为 NDJSON(5 个数据行对应 5 个 action+document 对),批量加载,然后验证数量 5 和映射类型。
JSON 数组文件:源 events.json 包含 4 个数组元素。将其转换为 4 个 bulk 行对(而非整个数组一个对)。验证 GET /{index}/_count 返回 4。
已准备好的 NDJSON:当文件交替包含 action 行和文档行时,验证格式并在确认目标索引和映射后直接传给 POST /_bulk。
不适用场景
- 持续或流式导入:使用 Elastic Agent 或 Beats 追踪日志和指标。
- 复杂数据丰富管道:单独设计服务端 ingest 管道;该技能仍在客户端将文件转换为 bulk NDJSON 后再加载。
- 索引到索引的复制或映射迁移:在索引之间 reindex,而非导出到文件。
- 非常大的二进制列式文件:先离线转换为 CSV 或 JSON,再遵循该技能。
操作映射
- GET / → elastic es info
- PUT /{index} → elastic es indices create --index '<index>' --mappings '<json>'
- DELETE /{index} → elastic es indices delete --index '<index>'
- POST /_bulk → elastic es bulk --index '<index>' --input-file '<ndjson-path>'
- GET /{index}/_count → elastic es count --index '<index>'
- GET /{index}/_mapping → elastic es indices get-mapping --index '<index>'
参考资料包括:NDJSON Bulk Format(CSV 和 JSON 数组转换、action 行语法、批次大小)、Mapping Design for Ingest(CSV 类型的显式映射、eval 风格模式)、Troubleshooting(错误计数、text 类型数字、bulk 项错误)。