如何在更新Elasticsearch文档时忽略具有空值的字段?

时间:2017-08-22 10:32:06

标签: java elasticsearch

当我尝试更新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")。

2 个答案:

答案 0 :(得分:1)

我认为您的问题是serializeNullsThe 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版本将非常有用