curl -X POST "http://localhost:9200/articles/_doc/1" -H "Content-Type: application/json" -d '{"title": "PHP Guide"}'
是向 Elasticsearch(ES),创建或更新 ID 为1的文档。
理解其每一部分,是掌握 ES REST API 与数据模型的核心。
一、HTTP 协议层:RESTful 请求结构
| 部分 | 说明 | 作用 |
|---|---|---|
curl | 命令行 HTTP 客户端 | 发送请求 |
-X POST | HTTP 方法 | 创建/更新文档(ES 中 POST/PUT 均可) |
http://localhost:9200 | ES 节点地址 | 默认 HTTP 端口 |
-H "Content-Type: application/json" | 请求头 | 告知 ES 负载为 JSON |
-d '{"title": "PHP Guide"}' | 请求体 | 文档数据 |
🔑核心:ES 完全遵循 RESTful 规范,所有操作 = HTTP 方法 + 路径 + JSON。
二、ES 路径语法:/articles/_doc/1的含义
📂路径分解
| 段 | 说明 | 规则 |
|---|---|---|
articles | 索引名(Index) | 类似数据库的“表” |
_doc | 文档类型(Type) | ES 7+ 固定为_doc(早期支持自定义) |
1 | 文档 ID(Document ID) | 唯一标识(不指定则 ES 自动生成) |
⚠️关键细节
- 索引(Index):
- 必须小写(ES 强制);
- 若不存在,ES 会自动创建(动态映射);
- 文档 ID:
- 指定 ID → 幂等操作(重复请求 = 覆盖);
- 不指定 ID → 用 POST
/articles/_doc,ES 生成 UUID;
💡
_doc是 ES 7+ 的规范,旧版(6.x)。
三、数据格式:JSON 文档的规则
📜文档结构
{"title":"PHP Guide","content":"Learn Elasticsearch","tags":["php","search"],"published":true,"views":100}- 字段类型:ES 自动推断(
"PHP Guide"→text,100→long); - 嵌套对象:支持 JSON 对象/数组;
🚫禁止内容
- 顶层不能有
.或空格("user.name"会被视为嵌套字段); - 不能包含控制字符(如
\x00);
✅ES 文档 = 无 schema 的 JSON 对象(但可预定义映射)。
4. 幂等性与操作语义
🔁指定 ID 的操作语义
| 操作 | 首次请求 | 重复请求 |
|---|---|---|
PUT /index/_doc/1 | 创建 ID=1 的文档 | 覆盖(更新) |
POST /index/_doc/1 | 同 PUT | 同 PUT |
⚠️ES 中 PUT/POST 在指定 ID 时行为一致(官方推荐用 PUT 创建,POST 不指定 ID)。
🌐响应示例
{"_index":"articles","_type":"_doc","_id":"1","_version":1,"result":"created",// 或 "updated""_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}result:created/updated;_version:乐观锁版本号(用于并发控制);
五、错误处理:常见失败场景
🚨1. 索引名大写
curl-X POST"http://localhost:9200/Articles/_doc/1"-d'{"title":"Test"}'- 错误:
{"error":"invalid_index_name_exception","reason":"Invalid index name [Articles], must be lowercase"}
🚨2. JSON 格式错误
curl-X POST... -d"{'title': 'Test'}"# 单引号非法- 错误:
{"error":"json_parse_exception","reason":"Unexpected character (''': ...)"}
🚨3. 内容类型缺失
curl-X POST... -d'{"title":"Test"}'# 无 -H "Content-Type: application/json"- 错误:
{"error":"parse_exception","reason":"request body is required"}
六、工程实践:PHP 中的安全等效实现
🧪1. 原生 cURL
<?php$url='http://localhost:9200/articles/_doc/1';$data=['title'=>'PHP Guide'];$ch=curl_init($url);curl_setopt_array($ch,[CURLOPT_CUSTOMREQUEST=>'POST',CURLOPT_POSTFIELDS=>json_encode($data),CURLOPT_HTTPHEADER=>['Content-Type: application/json'],CURLOPT_RETURNTRANSFER=>true]);$response=curl_exec($ch);$result=json_decode($response,true);curl_close($ch);if(isset($result['result'])){echo"文档{$result['result']},ID:{$result['_id']}\n";}🧪2. 使用官方客户端
<?php$client=ClientBuilder::create()->build();$response=$client->index(['index'=>'articles','id'=>1,'body'=>['title'=>'PHP Guide']]);echo"结果: ".$response['result'];七、终极心法:ES 是 JSON over HTTP
不要被路径语法迷惑,
而要理解“索引=数据库,文档=行,字段=列”。
- 脆弱操作:
- 手写 cURL 无错误处理 → 静默失败;
- 韧性操作:
- 用官方客户端 + 检查响应;
- 结果:
- 前者是脚本,后者是工程。
真正的 ES 能力,
不在“命令多熟”,
而在“协议多透”。
八、行动建议:今日 ES 写入验证
## 2025-10-07 ES 写入验证 ### 1. 手动执行 curl - [ ] 验证成功响应(result: created) ### 2. 故意触发错误 - [ ] 大写索引名 → 观察错误 - [ ] 单引号 JSON → 观察错误 ### 3. PHP 实现 - [ ] 用 cURL 和官方客户端各实现一次 ### 4. 检查响应 - [ ] 验证 _version 和 result 字段✅完成即掌握 ES 写入核心机制。
当你停止复制 curl 命令,
开始理解 HTTP + JSON + 路径语义,
Elasticsearch 就从工具,
变为数据管道基石。
这,才是专业工程师的搜索观。