Search code examples
elasticsearchelasticsearch-dsl

How remove an element in all documents of an index in elasticsearch?


I have list of documents in an index of Elasticsearch like below:

...
{
  "_index" : "index-name",
  "_type" : "_doc",
  "_id" : "table1c7151240c583e60c8e2cbad351",
  "_score" : 0.28322574,
  "_source" : {
    ...
    "table.tag" : {
      "datasources_keys" : [...],
      "tags" : [
        "6e7358e2bfc84c34af32a01f6d19e9b2",
        "ab450ae5c1734fb0aad5fed052b42023",
        "f725e3100bba4b5eb8a5199a2b3e62fc"
      ]
    }
  }
},
...

I wanna delete an element in all documents.. for example should remove a specified tag_id in tags like "6e7358e2bfc84c34af32a01f6d19e9b2" .. how should I write a script for that? Is there other way in elasticsearch?

I'm using this script.. but it doesnt work!!

POST index-name/_update_by_query
{
  "query": {
    "match":{
      "table.tag.tags": "6e7358e2bfc84c34af32a01f6d19e9b2"
    }
  },
  "script": {
    "source": "ctx._source['table.tag']['tags'] -= 6e7358e2bfc84c34af32a01f6d19e9b2",
    "lang": "painless"
  }
}

Solution

  • Here is a more concise way with implicit list iterations and if conditions (+ it's a one-liner 😉):

    POST index-name/_update_by_query
    {
      "query": {
        "match": {
          "table.tag.tags": "6e7358e2bfc84c34af32a01f6d19e9b2"
        }
      },
      "script": {
        "lang": "painless"
        "source": "ctx._source['table.tag']['tags'].removeIf(tag -> tag == params.tag);",
        "params": {
          "tag": "6e7358e2bfc84c34af32a01f6d19e9b2"
        }
      }
    }
    

    UPDATE

    You can add your second condition like this:

    ctx._source['table.tag']['tags'].removeIf(tag -> tag == params.tag);
    if (ctx._source['table.tag']['tags'].size() == 0) {
        ctx._source['table.tag'].remove('tags');
    }