当前位置: 首页 > 面试题库 >

Elasticsearch无痛脚本不会使用if条件替换嵌套对象字段值

洪胤
2023-03-14
问题内容

我刚开始使用ES,但仍然喜欢交易的技巧!!!我需要替换/覆盖嵌套对象类型的字段之一。这是示例文档:

{
"name":"db_ref",
"ref_counter":[
    {"ref_name":"test1","count":1},
    {"ref_name":"test2","count":2},
    {"ref_name":"test3","count":3}
    ]
}

映射以上文档:

{
    "settings": {
        "mappings": {
            "test_doc": {
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "ref_count": {
                        "type": "nested",
                        "ref_name": "string",
                        "count": "long"
                    }
                }
            }
        }
    }
}

我需要更新给定ref_name的计数字段值。例如,在上述情况下,如果 ref_name 是“ test1 ”,我希望新 计数
500 。我想出了下面的简单 脚本 来更改 数值,它可以正常执行而没有任何错误,但是我看不到该值正在更新。

curl -XPOST "http://localhost:9200/test_type/test_type/test_db/_update" -d '
{"script": "if (ctx._source.ref_counter.ref_name == cur_ref 
                && ctx._source.ref_counter.count == cur_count)
            {ctx._source.ref_counter.count = new_count };",
"params": {"cur_count": 1,"new_count": 500, "cur_ref": "test1"}}}'

以下是响应:

{"_index":"test_index","_type":"test_type","_id":"test_db","_version":2}

但是,当我看到该文档时,它仍然具有旧值。

有人可以帮我将计数值更改为新值吗?


问题答案:

我已经提到了以下查询。(Bulk update查询和per document更新查询)

核心逻辑在中script,这在两个查询中都相同。

我建议您按照逻辑进行自我解释。基本上,脚本会遍历嵌套文档,并根据您指定的条件对其进行count相应的更新。

批量更新-使用 __update_by_query_

POST <your_index_name>/_update_by_query
{
  "query": {
    "match_all": {}
  },
  "script": {
    "lang": "painless",
    "source": """
    if(ctx._source.ref_counter.contains(params.cur_data)){

      for(int i=0; i<ctx._source.ref_counter.size(); i++)
      {
        HashMap myKV = ctx._source.ref_counter.get(i);
        if(myKV.get(params.key_ref)==params.key_ref_value){
          myKV.put(params.key_count, params.key_count_value_new);
        }
      }

      //ctx._source.ref_counter.add(params.new_data);

    }""",
    "params": {
      "cur_data": { "ref_name": "test2", "count": 2},
      "new_data": { "ref_name": "test2", "count": 22},
      "key_ref": "ref_name",
      "key_ref_value": "test2",
      "key_count": "count",
      "key_count_value_new": 80

  }}
}

每个文档更新-使用 文档ID

POST <your_index_name>/<your_mapping>/1/_update
{
  "script": {
    "lang": "painless",
    "source": """
    if(ctx._source.ref_counter.contains(params.cur_data)){

      for(int i=0; i<ctx._source.ref_counter.size(); i++)
      {
        HashMap myKV = ctx._source.ref_counter.get(i);
        if(myKV.get(params.key_ref)==params.key_ref_value){
          myKV.put(params.key_count, params.key_count_value_new);
        }
      }

      //ctx._source.ref_counter.add(params.new_data);

    }""",
    "params": {
      "cur_data": { "ref_name": "test2", "count": 2},
      "new_data": { "ref_name": "test2", "count": 22},
      "key_ref": "ref_name",
      "key_ref_value": "test2",
      "key_count": "count",
      "key_count_value_new": 80

  }
}
}

希望对您有所帮助,如有任何疑问,请与我们联系!



 类似资料:
  • 以下是我的查询的简化版本: 希望有办法解决这个... 提前感谢你的帮助

  • 我想从特定字段中搜索关键字并返回文档。在这些文档之上,我希望遍历每个嵌套对象,并从选定文档的同一特定字段中再次搜索关键字。 如果关键字存在,则检查:如果布尔isCurrent = True,则设置isCurrent=0,并将该值追加到列表中;否则,如果isCurrent = False,则取当前日期时间的差值,结束日期时间,并获得以月为单位的值,并将该值追加到列表中。 最后,从每个文档的列表中获取

  • 问题内容: 我想在每个更新时间将一个对象添加到字段中。 例如,我有一个文档: 下次,我想在测试字段中添加一个对象并保存旧对象。结果是: 如何实现? 编辑 我使用脚本: 但是,我得到了例外: 编辑 现在,我想添加一个字段以确保更新或插入对象。例如: 当我更新字段时,当id存在时,我将更新对象。相反,我将插入对象。 问题答案: 我建议尝试这样的脚本,该脚本在参数中带有两个参数。它将检查任何嵌套对象是否

  • 我对elasticsearch和spring数据elasticsearch非常陌生,在查询嵌套对象时遇到了一些问题。 我使用ElasticSearch存储库在ElasticSearch中保存一个嵌套模型实例。因此,elasticsearch中只有一个条目包含所有数据,据我所知,这意味着我有一个嵌套文档。 我需要使用Criteria实现一个相对复杂的查询来迭代构建查询。当我尝试使用点表示法访问嵌套属

  • 有没有办法在嵌套查询中使用“script_fields”,将字段添加到返回的inner_hits?例: 我执行n个嵌套查询,向每个嵌套查询传递一组特定的参数。这个想法是让源脚本根据提供的参数为每个内部命中的重叠字段分配一个值。 看起来在同一嵌套路径上执行更多的嵌套查询,定义不同的inner_hits使 ES 去除inner_hits匹配项。例: 如果像这样运行更多的嵌套查询,我会得到正确的匹配项,

  • 我没有Java经验,我对elasticsearch无痛脚本语言有问题。(这个名字叫“无痛”,选得不好)。 对于下面的代码,我得到了错误: 无法应用 [ 我用(float) doc['newPrice']将它绑定为float 然后我改为<code>“Double price=((Double)doc['discountPrice'] 并收到: “无法从[双]铸造到[双]。” 有人可以帮助我,尝试了很