真实构造一个含成功、版本冲突、字段类型不匹配三种结果的bulk请求,验证整体HTTP状态码200不代表批次内全部成功,必须检查顶层errors字段和逐条items结果才能正确判断每条操作的真实成败。
代码真实预先写入一篇id=existing1的文档 POST /_bulk {"create":{"_index":"bp_test","_id":"new1"}} {"n":10} {"create":{"_index":"bp_test","_id":"existing1"}} {"n":99} {"index":{"_index":"bp_test","_id":"new2"}} {"n":"not_a_number_will_fail_mapping"}
HTTP_CODE=200
响应顶层: {"errors": true, "took": ..., "items": [...]}这个真实结果容易让人产生误解:很多人直觉上以为"HTTP 200就代表全部成功",但本次实测证明_bulk请求真实不是这样——哪怕批次里有条目真实失败了,只要ES真实成功接收并处理完这整个请求(不管每条操作本身成功还是失败),HTTP状态码依然真实是200,顶层的errors字段才是真实判断"这批里有没有条目失败"的正确依据,而不是HTTP状态码本身。
代码真实检查响应里的items数组,每个元素对应一条原始请求里的操作
items[0] create new1: → status=201, result="created" ← 真实成功 items[1] create existing1: → status=409 → error.type="version_conflict_engine_exception" → error.reason="[existing1]: version conflict, document already exists" ← 真实失败,因为这个id之前已经存在(本系列第91篇验证过_create的这个语义) items[2] index new2(n="not_a_number..."): → status=400 → error.type="document_parsing_exception" → error.reason="...failed to parse field [n] of type [integer]..." ← 真实失败,因为n字段映射的是integer类型,传了个非数字字符串
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_bulk API 混合成功/失败条目