Search code examples
elasticsearchelastic4s

Elastic4s/Elasticsearch - Is there a way to update a document and also remove fields?


My application gets change events for a certain object, and from these events, I build a doc that is used to upsert into elasticsearch:

      updateById(
        "index",
        "id"
      ).doc(changeEvent)
        .docAsUpsert(true)

The problem is, a change event can be nulling out a field/removing a field in Elasticsearch. Would something like this work? Is there a way to do this in one roundtrip?

      updateById(
        "index",
        "id"
      ).doc(changeEvent)
        .docAsUpsert(true)
        .script(
          Script(
            "for (field in params.removeFields) {ctx._source.remove(field)}",
            params = removeMap
          )
        )
        .scriptedUpsert(true)

Or do I just need to send one upsert request, and a separate script request that will iterate through the params and remove the fields?


Solution

  • You cannot provide a script and doc at the same time, i.e. you can't do a docAsUpsert and scriptedUpsert in the same call.

    However, since via doc you cannot remove fields, I'd do it simply via script. In the script params you can provide two hashes:

    • changeFields: all the fields to add or change their value
    • removeFields: all the fields to remove

    The script would then become:

    ctx._source.putAll(params.changeFields);
    for (field in params.removeFields) {ctx._source.remove(field)}