当我尝试更新elasticsearch中的文档而未指定某些字段时,它会将该字段更新为null。这是我使用的代码。
public class DocumentModel {
@Id
private String id;
private Integer name;
private String gender;
private String url;
private String documentID;
------------------
------------------
getters and setters
}
用于索引文档的代码是:
Gson gson = new GsonBuilder().serializeNulls().create();
String json = gson.toJson(documentModel);
IndexRequest indexRequest = new IndexRequest(indexName, typeName, documentModel.getId());
indexRequest.source(json);
UpdateRequest updateRequest = new UpdateRequest(indexName, typeName, documentModel.getId());
updateRequest.doc(json);
updateRequest.upsert(indexRequest);
updateRequest.fields("documentID");
UpdateResponse updateResponse = elasticsearchTemplate.getClient().update(updateRequest).actionGet();
假设输入(documentModel)是(第一次索引文档):
{"id":1,"name":"tom","gender":"male","url":"http://www.google.com","documentID":1}
它将索引为:
{
"_index": "index",
"_type": "type",
"_id": "1",
"_score": 1,
"_source": {
"name":"tom",
"gender":"male",
"url":"http://www.google.com",
"documentID":1
}
}
但是当我尝试用输入更新同一文档时:
{"id":1,"name":"archana","gender":"female"}
它将更新为:
{
"_index": "index",
"_type": "type",
"_id": "1",
"_score": 1,
"_source": {
"name":"archana",
"gender":"female",
"url":null,
"documentID":null
}
}
问题是未作为输入提供的字段(例如,' url',#document;')在更新文档时设置为null。但我希望该字段仍然与旧值,除非该值不为空(例如" url":" http://www.google.com")。
答案 0 :(得分:1)
我认为您的问题是serializeNulls
。 The docs say:
配置Gson以序列化空字段。默认情况下,Gson省略序列化期间为空的所有字段。
我认为这意味着您向Elasticsearch发送了一个类似于:
的请求POST /index/type/1/_update
{
"doc": {
"name":"archana",
"gender":"female",
"url":null,
"documentID":null
}
}
告诉Elasticsearch你要用null
来写这些值。如果你不想写它们,你需要将它们完全排除在请求之外,我认为你可以通过摆脱serializeNulls()
电话来完成它。
这是你必须在代码或脚本更新中处理的事情(虽然我不能想到你想要这样做的原因,除非你不控制代码制作请求),或者您可以编写一个插件来添加此行为。
答案 1 :(得分:0)
Elastic通过使用_update Rest API调用来支持增量更新,所以我假设如果你这样做,Java API也应该这样做
updateRequest.update(indexRequest)
而不是
updateRequest.upsert(indexRequest)
请注意,如果文档不存在,显式更新将失败,因此您需要在发出更新命令之前检查它。
提供Elastic和Java API版本将非常有用