Is there a way to update a document with a Painless script without changing the order of unaffected fields?

1.5k Views Asked by At

I'm using Elasticsearch's Update by Query API to update some documents with a Painless script like this (the actual query is more complicated):

POST ts-scenarios/_update_by_query?routing=test
{
  "query": {
    "term": { "routing": { "value": "test" } }
  },
  "script": {
    "source": """ctx._source.tagIDs = ["5T8QLHIBB_kDC9Ugho68"]"""
  }
}

This works, except that upon reindexing, other fields get reordered, including some classes which are automatically (de)serialized using JSON.NET's type handling. That means a document with the following source before the update:

  {
    "routing" : "testsuite",
    "activities" : [
      {
        "$type" : "Test.Models.SomeActivity, Test"
      },
      {
        "$type" : "Test.Models.AnotherActivity, Test",
        "CustomParameter" : 1,
        "CustomSetting" : false
      }
    ]
  }

ends up as

  {
    "routing" : "testsuite",
    "activities" : [
      {
        "$type" : "Test.Models.SomeActivity, Test"
      },
      {
        "CustomParameter" : 1,
        "CustomSetting" : false,
        "$type" : "Test.Models.AnotherActivity, Test"
      }
    ],
    "tagIDs" : [
      "5T8QLHIBB_kDC9Ugho68"
    ]
  }

which JSON.NET can't deserialize. Is there a way I can tell the script (or the Update by Query API) not to change the order of those other fields?

In case it matters, I'm using Elasticsearch OSS version 7.6.1 on macOS. I haven't checked whether an Ingest pipeline would work here, as I'm not familiar with them.


(It turns out I can make the deserialization more flexible by setting the MetadataPropertyHandling property to ReadAhead, as mentioned here. That works, but as mentioned it may hurt performance and there might be other situations where field order matters. Technically, it shouldn't; JSON isn't XML, but there are always edge cases where it does matter.)

0

There are 0 best solutions below