1

In ES 6, I have indexed the following doc:

PUT test/doc/_bulk?refresh
{"index":{"_id":1}}
{"prop1":"foo","prop2":[{"a":"123"},{"a":"456"}]}

I need to remove the element from "prop2" that has a value of "456" for "a"

The remove() method in Painless needs an index, so I can do this:

POST /test/1/_update
{
"script": {
"lang": "painless",
"source": "ctx._source.list.remove(ctx._source.list.indexOf(params.obj))",
"params" : {"obj" : {"a": "456"}}  
}}

The problem is that each object in prop2 actually has a dozen other keys with varying values - so I can't isolate the element with a param. It requires some kind of query or filter to say "delete any element that has a value of '456' for 'a'."

In Python, if I have a list like so:

l=[{'a': '123', "b": '321'}, {'a': '456','b':'654'}]

I can get the index I need with this:

[l.index(x) for x in l if x['a'] == '456'][0]

But I can't figure out the Painless approach (don't know Java, btw). Tried several things; this fails with a script compile error:

POST /test/doc/1/_update
{
  "script": {
    "lang": "painless",
    "source": """
      l = ctx._source.list
      for (x in l){
        if (x['a'] == '456') {
          idx = l.indexOf(x) 
          l.remove(idx)
        }
      }
    """
}}
kgeo
  • 412
  • 5
  • 19
  • you can also use ingest API at index time to do this. using the foreach processor https://www.elastic.co/guide/en/elasticsearch/reference/current/foreach-processor.html go over all elements in the list and check the condition. – Opster Elasticsearch Expert Feb 10 '19 at 09:28
  • In this case, the list has elements from multiple contributors. Periodically, if they update their dataset, I need to remove and/or replace everything from a particular contributor. The alternative is parent-child - thought I'd try this first. Thanks. – kgeo Feb 10 '19 at 16:00

0 Answers0