首页 > 解决方案 > elasticsearch的bulk api能保证文档写入es有序吗?

问题描述

我检查了官方文档和文档 syas:

批量 API 的响应包含请求中每个操作的单独结果,按提交的顺序返回。单个操作的成功或失败不会影响请求中的其他操作。

官方文档并没有说明如果文档具有相同的主键'_id',是否按顺序写入elasticsearch。

这里有一个例子。我有 3 个具有相同 pk id=1 的文档,其他字段不同。我为这 3 个文档创建了 3 个 UpdateRequest。我按顺序将这些文档添加到 BulkRequest。提交给es客户端后,我可以确保这些文档按照我添加到批量请求的顺序在es中执行吗?

// Three docs with same id but different non-pk field value 
Map<String,String> doc1 = new HashMap;
doc1.put("_id","1");
doc1.put("other_column","columnValue1");

Map<String,String> doc2 = new HashMap;
doc1.put("_id","1");
doc1.put("other_column","columnValue2");

Map<String,String> doc3 = new HashMap;
doc1.put("_id","1");
doc1.put("other_column","columnValue3");


//prepare 3 update Request
 UpdateRequest updateRequest1 = new UpdateRequest(index,type,"1").docAsUpsert(true).setDoc(doc1);
 UpdateRequest updateRequest2 = new UpdateRequest(index,type,"1").docAsUpsert(true).setDoc(doc2);
 UpdateRequest updateRequest3 = new UpdateRequest(index,type,"1").docAsUpsert(true).setDoc(doc3);



//add the to bulk request
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(indexRequest1);
bulkRequest.add(indexRequest2);
bulkRequest.add(indexRequest3);

//execute by client
restHighLevelClient.bulk(bulkRequest);

//if doc2 write into elasticsearch failed, doc1 and doc2 may also be executed successfully as the official doc said. Is it right?



但是,文档说单个操作的成功或失败不会影响请求中的其他操作。就我而言,如果 es 请求中具有相同 pk 的文档有部分失败文档,而其他文档成功写入 es。显然,这意味着它们没有按顺序写入es。es客户端批量api不能保证doc按顺序写入es的结论是对的吗?

标签: elasticsearch

解决方案


如果您仅使用批量处理器插入记录,则在刷新期间,根据时间戳以有序方式刷新记录。因此,文档将使用特定文档 ID 的最新数据进行更新。假设您索引文档然后将其删除。所以最终的结果将是 doc 被删除。

但是,如果除了批量之外还有正常的索引,并且如果使用批量和常规索引 api 对相同的 id 进行索引,则不会保持排序。因为冲洗可能发生在不同的时间。假设您使用批量索引 id 为 1 的文档,然后使用常规索引 api 删除了 id 1。如果批量刷新间隔设置为 5 秒,那么您删除的索引可能会在 es 中保持索引。


推荐阅读