Elasticsearch 5与NEST 5中获取异步更新任务失败集合问题
问题:NEST 5无法获取UpdateByQuery异步任务的失败文档ID?
我正在使用Elasticsearch 5和NEST 5执行异步批量更新操作,具体是用UpdateByQuery并设置了WaitForCompletion(false)让任务后台运行。现在遇到个麻烦:用NEST的GetTask方法获取任务状态时,返回的对象里找不到Failures集合,但直接在Kibana里调用GET _tasks/{taskId}或者查看ES的原始响应,明明能看到包含版本冲突文档ID的Failures信息。有没有办法通过NEST拿到这些失败的文档ID?
我的代码片段
UpdateByQuery 实现
query .Index(allIndexesStr) .Query(q => ... ) .WaitForCompletion(false) .Script(script => script .Inline(scriptStr) .Params(p => ... ) ) ...
获取任务状态的代码
new ElasticClient(ESConnectionSettings.Instance.Settings).GetTask(taskId);
解决方案
在NEST 5的版本里,GetTaskResponse确实没有直接封装Failures这个属性,这是早期客户端映射的一个小疏漏。不过你可以通过两种方式拿到这些失败信息:
1. 从响应中提取原始JSON解析
你可以借助GetTaskResponse的ApiCall.ResponseBodyInBytes属性拿到ES返回的原始响应内容,再用JSON库解析出Failures数组:
var client = new ElasticClient(ESConnectionSettings.Instance.Settings); var taskResponse = client.GetTask(taskId); // 把原始字节转成JSON字符串 var rawResponseJson = Encoding.UTF8.GetString(taskResponse.ApiCall.ResponseBodyInBytes); // 用Newtonsoft.Json解析成动态对象(或者你也可以定义强类型类) var dynamicResult = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(rawResponseJson); // 提取Failures集合 var failures = dynamicResult.task.status.failures; foreach (var failure in failures) { var conflictDocumentId = failure.id; Console.WriteLine($"版本冲突的文档ID:{conflictDocumentId}"); // 这里可以添加你的处理逻辑 }
2. 使用NEST的低级客户端发送请求
如果觉得解析原始JSON麻烦,也可以用NEST自带的低级客户端直接请求,它会返回更原始的响应内容:
var client = new ElasticClient(ESConnectionSettings.Instance.Settings); var lowLevelClient = client.LowLevel; // 发送GET _tasks/{taskId}请求 var lowLevelResponse = lowLevelClient.GetTask<StringResponse>(taskId); // 同样解析JSON获取Failures var dynamicResult = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(lowLevelResponse.Body); var failures = dynamicResult.task.status.failures; // 处理失败文档ID foreach (var failure in failures) { var conflictId = failure.id; // 你的处理代码 }
补充说明
这两种方法本质都是绕开NEST封装的局限,直接获取ES返回的完整响应数据。因为在Elasticsearch 5的API里,_tasks端点确实会返回任务的失败详情,只是NEST 5的客户端没有把这个字段映射到响应对象里而已。
内容的提问来源于stack exchange,提问作者Adriano
相关产品推荐
相关产品推荐

