> 技术文档 > ES 更新或新增

ES 更新或新增

 UpdateRequest updateRequest = new UpdateRequest(EsOperateTables.ORDER_TRACE_DETAIL.getAlias(), BizConstant.ES_DEFAULT_TYPE, orderTraceDetail.getId().toString());  updateRequest.doc(jsonStr, XContentType.JSON);  updateRequest.docAsUpsert(true);  restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);

只做更新吗,不存在会新增吗

您的问题涉及到 Elasticsearch 的更新操作逻辑。在您提供的代码中,updateRequest.docAsUpsert(true) 这个设置非常关键,它决定了当文档不存在时的行为。

关于 UpdateRequest 的行为

1. 默认行为(无 docAsUpsert 或设为 false)

java

UpdateRequest updateRequest = new UpdateRequest(index, type, id);updateRequest.doc(jsonStr, XContentType.JSON);// updateRequest.docAsUpsert(false); // 默认就是false
  • 只做更新:如果文档不存在,会抛出 DocumentMissingException

  • 不会新增:不会自动创建新文档

2. 使用 docAsUpsert(true) 的行为

java

UpdateRequest updateRequest = new UpdateRequest(index, type, id);updateRequest.doc(jsonStr, XContentType.JSON);updateRequest.docAsUpsert(true); // 关键设置
  • 智能判断

    • 如果文档存在:执行更新操作

    • 如果文档不存在:执行插入操作(相当于 upsert)

  • 既会更新也会新增:这是一个\"更新或插入\"的操作

3. 您提供的代码分析

java

UpdateRequest updateRequest = new UpdateRequest( EsOperateTables.ORDER_TRACE_DETAIL.getAlias(), BizConstant.ES_DEFAULT_TYPE, orderTraceDetail.getId().toString()); updateRequest.doc(jsonStr, XContentType.JSON);updateRequest.docAsUpsert(true); // 这个设置为true是关键restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);

由于您设置了 docAsUpsert(true),所以这个操作是:

  • 文档存在时:更新该文档

  • 文档不存在时:插入新文档(使用提供的jsonStr作为内容)

实际应用建议

  1. 需要严格区分插入和更新时

    • 使用 index API 进行明确插入

    • 使用普通 update (不带docAsUpsert) 进行明确更新

  2. 需要upsert功能时

    • 就像您现在这样设置 docAsUpsert(true)

    • 这是Elasticsearch中非常常用的模式

  3. 性能考虑

    • Upsert操作比单纯插入或更新开销稍大

    • 在明确知道文档存在的情况下,可以不用docAsUpsert

完整示例代码

java

// 创建请求UpdateRequest request = new UpdateRequest(\"index\", \"type\", \"1\");// 准备文档内容Map jsonMap = new HashMap();jsonMap.put(\"field1\", \"value1\");jsonMap.put(\"field2\", \"value2\");// 设置更新内容request.doc(jsonMap); // 关键设置:启用upsertrequest.docAsUpsert(true);// 执行请求UpdateResponse response = client.update(request, RequestOptions.DEFAULT);// 检查结果if (response.getResult() == DocWriteResponse.Result.CREATED) { System.out.println(\"文档不存在,已新增\");} else if (response.getResult() == DocWriteResponse.Result.UPDATED) { System.out.println(\"文档已存在,已更新\");}

您当前的代码实现是正确的upsert模式,既会更新现有文档,也会在文档不存在时新增文档。