ARods
ARods

Reputation: 479

How to swap and migrate index field value in different documents by Elasticsearch query

Say I have an Elasticsearch index Employee with field emp_id and I mistakenly saved the documents with emp_id=1 instead of emp_id=2 and emp_id=2 instead of emp_id=1.

Sample documents on index Employee

[
    {
        "emp_id": "1",
        "name": "aaaa"
    },
    {
        "emp_id": "2",
        "name": "bbbb"
    },
    {
        "emp_id": "3",
        "name": "cccc"
    },
    {
        "emp_id": "4",
        "name": "dddd"
    }
]

Now I want to change/update all the document's emp_id value from emp_id=1 to emp_id=2 and also change emp_id=2 to emp_id=1 using an Elasticsearch query.

So the above documents should be changed/updated like this:

[
    {
        "emp_id": "2",
        "name": "aaaa"
    },
    {
        "emp_id": "1",
        "name": "bbbb"
    },
    {
        "emp_id": "3",
        "name": "cccc"
    },
    {
        "emp_id": "4",
        "name": "dddd"
    }
]

Note: emp_id = 1,2,3,4 are all present in the same index. I just want to swap and migrate the emp_id 1 and 2's values without affecting other documents in index.

How to do this in Elasticsearch in a atomic fashion?

Any help would be greatly appreciated. Thanks in advance!

Upvotes: 3

Views: 199

Answers (1)

Val
Val

Reputation: 217254

You can do this with an ingest pipeline and the _update_by_query endpoint:

First create an ingest pipeline with a script processor that will do the atomic change

PUT _ingest/pipeline/swap_ids
{
  "processors": [
    {
      "script": {
        "source": """
        ctx.id = (ctx.id == '1') ? '2' : '1';
        """
      }
    }
  ]
}

Then, select all documents to be updated (i.e. the ones with id = 1 or 2) and update them all using the pipeline you just created:

POST test/_update_by_query?pipeline=swap_ids
{
  "query": {
    "terms": {
      "id": ["1", "2"]
    }
  }
}

That's it!

Upvotes: 2

Related Questions