当前位置: 首页 > 知识库问答 >
问题:

如何执行弹性搜索_update_by_query使用无痛脚本-复杂条件

查锦程
2023-03-14

你能建议如何更新基于条件字段的文档(使用脚本-我猜是无痛的)吗?

其目的是添加/删除文档中的值

所以如果我有这些输入文档:

doc //1st
{
   "Tags":["foo"],
   "flag":"true"
}


doc //2nd
{
   "flag":"true"
}

doc //3rd
{
   "Tags": ["goo"],
   "flag":"false"
}

我想表演这样的东西:

使用以下命令更新具有“flag=true”的所有文档:

  • 添加标签:"me","one"
  • 已删除标签:“goo”、“foo”

所以预期结果应该是这样的:

doc //1st
{
   "Tags":["me","one"],
   "flag":"true"
}


doc //2nd
{
   "Tags":["me","one"],
   "flag":"true"
}

doc //3rd
{
   "Tags": ["goo"],
   "flag":"false"
}

共有1个答案

邹英发
2023-03-14

创建映射:

PUT documents
{
    "mappings": {
        "document": {
            "properties": {
                "tags": {
                    "type": "keyword",
                    "index": "not_analyzed"
                },
                "flag": {
                    "type": "boolean"
                }
            }
        }
    }
}

插入第一个文档:

PUT documents/document/1
{
    "tags":["foo"],
    "flag": true
}

插入第二个文档(请记住,对于空标签,我指定了空标签数组,因为如果您根本没有字段,您将需要检查脚本中是否存在字段):

PUT documents/document/2
{
    "tags": [],
    "flag": true
}

添加第三个文档:

PUT documents/document/3
{
    "tags": ["goo"],
    "flag": false
}

然后运行_update_by_query,它有两个数组作为参数,一个用于添加元素,另一个用于删除元素:

POST documents/_update_by_query 
{
    "script": {
        "inline": "for(int i = 0; i < params.add_tags.size(); i++) { if(!ctx._source.tags.contains(params.add_tags[i].value)) { ctx._source.tags.add(params.add_tags[i].value)}} for(int i = 0; i < params.remove_tags.size(); i++) { if(ctx._source.tags.contains(params.remove_tags[i].value)){ctx._source.tags.removeAll(Collections.singleton(params.remove_tags[i].value))}}",
        "params": {
            "add_tags": [
                {"value": "me"},
                {"value": "one"}
            ],
            "remove_tags": [
                {"value": "goo"},
                {"value": "foo"}
            ]
        }
    },
    "query": {
        "bool": {
            "must": [
                {"term": {"flag": true}}
            ]
        }
    }
}

如果您随后进行以下搜索:

GET documents/_search

你会得到以下结果(我认为这是你想要的):

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [{
                "_index": "documents",
                "_type": "document",
                "_id": "2",
                "_score": 1,
                "_source": {
                    "flag": true,
                    "tags": [
                        "me",
                        "one"
                    ]
                }
            },
            {
                "_index": "documents",
                "_type": "document",
                "_id": "1",
                "_score": 1,
                "_source": {
                    "flag": true,
                    "tags": [
                        "me",
                        "one"
                    ]
                }
            },
            {
                "_index": "documents",
                "_type": "document",
                "_id": "3",
                "_score": 1,
                "_source": {
                    "tags": [
                        "goo"
                    ],
                    "flag": false
                }
            }
        ]
    }
}
 类似资料:
  • 我是ES的新手,我正在尝试使用聚合编写搜索查询。 在写同样的东西时,我面临着无痛脚本的问题。 哪里可以得到完整的无痛脚本文档,用于弹性搜索?

  • 我有一个弹性查询脚本,用于使用我给出的参数计算地面距离,我必须在多个查询中使用它。是否有一种方法可以避免这种重复,例如,有一种计算全局变量并在所有脚本中使用它的方法。在本例中,我希望计算<code>距离 映射:

  • 我在elasticsearch中创建了一个观察器,当我们在索引中10分钟没有新条目或事件时,它会报告,这可以通过查看条目中的源字段来进一步划分。 我只得到了索引的最后10分钟,并查看了桶中不存在哪个源。 为此,我首先创建我们收到的所有源类型的列表,然后从返回的存储桶键创建一个列表。然后,我想比较列表以查看缺少哪个列表,然后将其传递到消息中。 我在for循环中遇到了一个通用错误。任何反馈对弹性和无痛

  • 想知道是否有人知道为什么这个查询更新运行良好,但即使任务运行到完成并声称所有记录都已更新,也不会删除任何内容?我可以使用相同的语法删除所有人员对象,而不会出现任何问题。为什么 ES 不删除对象属性? 现在,如果我使用从上述调用返回的ID观看任务 GET/_ tasks/qle uj 8 jqqgopfgse ZL 7 u 9 q:1776664 我得到了这个(简短的版本),声称所有记录都已更新。然

  • 我目前正在使用Elastic search 5.2,并尝试使用以下rest api执行upsert操作: > http://ip:9200/indexname/typename/id/_update Json有效载荷: } 此api执行以下操作: 1.)如果在弹性搜索中没有找到索引,则使用upsert字段中提供的json创建索引。< br> 2。)如果索引存在,那么它通过运行文档中提供的简单脚本来

  • 我想将地理信息的旧数据重新索引到地理点。 以前的数据包含这种格式的位置。 我想像这样在数组中的地理点中重新索引位置 这是映射 这是我执行重新索引的请求。 问题它没有覆盖位置:{} 到位置:[]