简体   繁体   English

在 ElasticSearch 中从数组中删除元素/对象,然后匹配查询

[英]Remove elements/objects From Array in ElasticSearch Followed by Matching Query

I have below types documents.我有以下类型的文件。

{
"_index": "example1",
"_type": "doc",
"_id": "8036",
"_score": 1,
"_source": {
  "user": "kimchy8036",
  "postDate": "2009-11-15T13:12:00",
  "locations": [
    [
      72.79887719999999,
      21.193036000000003
    ],
    [
      -1.8262150000000001,
      51.178881999999994
    ]
  ]
  }
} 

And below is mapping:下面是映射:

   {
        "example1": {
        "mappings": {
        "doc": {
        "properties": {
        "locations": {
        "type": "geo_point"
        },
        "postDate": {
        "type": "date"
        },
        "status": {
        "type": "long"
        },
        "user": {
        "type": "text",
        "fields": {
        "keyword": {
        "type": "keyword",
        "ignore_above": 256
        }
        }
        }
        }
        }
        }
        }
            }

I can add multiple locations using below query.我可以使用以下查询添加多个位置。

POST /example1/_update_by_query
    {
    "query": {
    "match": {
    "_id": "3"
    }
    },
    "script" : {
    "lang":"painless",
    "inline": "ctx._source.locations.add(params.newsupp)",
    "params":{
    "newsupp":[-74.00,41.12121 ]
    }}
    }

But not able remove array objects from locations.但无法从位置删除数组对象。 I have tried below query but working.我试过下面的查询但工作。 POST example1/doc/3/_update { POST 示例 1/doc/3/_update {

    "script" :
    {
    "lang":"painless",
    "inline":"ctx._source.locations.remove(params.tag)",
    "params":{
    "tag":[-74.00,41.12121]
    }
    }
    }

Kindly let me know where i am doing wrong here.请让我知道我在这里做错了什么。 I am using elastic version 5.5.2我使用的是弹性版本 5.5.2

Unlike add() , remove() takes the index of the element and remove it.add()不同, remove()获取元素的索引并将其删除。

Your ctx._source.locations in painless is an ArrayList .你的ctx._source.locations是一个ArrayList It has List 's remove() method:它有Listremove()方法:

E remove(int index) E 删除(整数索引)

Removes the element at the specified position in this list (optional operation).移除此列表中指定位置的元素(可选操作)。 ... ...

See Painless API - List for other methods.有关其他方法,请参阅无痛 API - 列表

See this answer for example code.有关示例代码,请参阅此答案

In painless scripts, Array.remove() method removes by index, not by value.在无痛脚本中, Array.remove()方法按索引而不是按值删除。

Here's a working example that removes array elements by value in Elasticsearch script:这是一个在 Elasticsearch 脚本中按值删除数组元素的工作示例:

POST objects/_update_by_query
{
    "query": {
        ...  // use regular ES query to remove only in relevant documents
    },
    "script": {
        "source": """
            if (ctx._source[params.array_attribute] != null) {
                for (int i=ctx._source[params.array_attribute].length-1; i>=0; i--) {
                    if (ctx._source[params.array_attribute][i] == params.value_to_remove) {
                        ctx._source[params.array_attribute].remove(i);
                    }
                }
            }
        """,
        "params": {
            "array_attribute": "<NAME_OF_ARRAY_PROPERTY_TO_REMOVE_VALUE_IN>",
            "value_to_remove": "<VALUE_TO_REMOVE_FROM_ARRAY>",
        }
    }
}

You might want to simplify script, if your script shall only remove values from one specific array attribute.如果您的脚本只从一个特定的数组属性中删除值,您可能想要简化脚本。 For example, removing "green" from document's .color_list array:例如,从文档的.color_list数组中删除"green"

_doc/001 = {
    "color_list": ["red", "blue", "green"]
}

Script to remove "green" :删除"green"脚本:

POST objects/_update_by_query
{
    "query": {
        ...  // use regular ES query to remove only in relevant documents
    },
    "script": {
        "source": """
            for (int i=ctx._source.color_list.length-1; i>=0; i--) {
                if (ctx._source.color_list[i] == params.color_to_remove) {
                    ctx._source.color_list.remove(i);
                }
            }
        """,
        "params": {
            "color_to_remove": "green"
        }
    }
}
"script" : {
    "lang":"painless",
    "inline":"ctx._source.locations.remove(params.tag)",
    "params":{
      "tag":indexToRemove
    }
}

If with ctx._source.locations.add(elt) You add the element, with ctx._source.locations.remove(indexToRemove) , you remove by the index of element in the array.如果使用ctx._source.locations.add(elt)添加元素,使用ctx._source.locations.remove(indexToRemove) ,则通过数组中元素的索引删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM