Search code examples
c#elasticsearch.net-corenest

How can I delete a field value from an Elasticsearch document using NEST?


I am using Nest to insert/update Documents in Elasticsearch. Here's a sample POCO class that I use to map the Document...

public class MyClass
{
    public string Id { get; set; }
    public decimal? MyField { get; set; }
}

This works as expected...When I add the Document, if the nullable field MyField has a value, it is returned in the JSON. If the nullable field doesn't have a value, it's not returned in the _source JSON because null values aren't stored.

However, there might be times where I need to update a single document and remove the value from a single field. That is, when I first insert the document, MyField has a value and is returned in the Elasticsearch JSON result. Then later, for whatever reason, I need to remove that value.

I am using partial document updates, and if possible, would prefer to keep it like that. (The full Document model I'm using will have 100+ fields, and my index will eventually have 100M+ records.) So, I'm looking for the most efficient way possible to partially update the documents.

Thanks in advance!


Solution

  • Think how would you do it just using api? there are several ways. for example like this:

    // kibana version
    POST my_index/_update_by_query
    {
      "query": {
        "ids": {
          "values": [
            "12345"
          ]
        }
      },
      "script": {
        "source": "ctx._source.myField = null"
      }
    }
    
    // nest version
    var response = client.UpdateByQuery<CustomerDto>(u => u
        .Query(q => q
            .Ids(i => i.Values(12345))
        )
        .Script("ctx._source.flag = null")
        //.Conflicts(Conflicts.Proceed)
        .Refresh(true)
    );
    

    or this:

    // kibana version
    POST my_index/my_type/12345/_update
    {
      "script": {
        "source": "ctx._source.remove('myField')"
      }
    }
    
    // nest version
    var response = client.Update<CustomerDto>(
        new UpdateDescriptor<CustomerDto, CustomerDto>("index_name", "type", 12345)
            .Script(s => s.Source("ctx._source.remove('middleName')")));