【问题标题】:Is it possible to update nested field by query?是否可以通过查询更新嵌套字段?
【发布时间】:2019-11-20 20:30:38
【问题描述】:

我正在使用按查询更新插件 (https://github.com/yakaz/elasticsearch-action-updatebyquery/) 通过查询更新文档。 在我的例子中,文档中有嵌套字段,映射是这样的:

"mappings": {
  "mytype": {
    "properties": {
      "Myfield1": {
        "type": "nested",
        "properties": {
          "field1": {
            "type": "string"
          },
          "field2": {
            "type": "long"
          }
        }
      },
      "Title": {
        "type": "string"
      }
    }
  }
}

然后我想通过以下请求通过查询更新嵌套字段Myfield1

但不幸的是,它不起作用。

{
  "query": {
    "match": {
      "Title": "elasticsearch"
    }
  },
  "script": "ctx._source.Myfield1 = [{'nestfield1':'foo blabla...','nestfield2':100},{'nestfield1':'abc...','nestfield2':200}]"
}

查询更新是否支持嵌套对象?

顺便说一句:还有其他通过查询更新文档的方法吗?

查询插件更新是唯一的选择吗?

【问题讨论】:

  • 嗯,我很确定,您可以在没有任何插件的情况下更新文档,只需索引具有相同 ID 的文档 - 它将被替换
  • 是的,我可以按 id 部分更新文档。但是我首先需要知道要更新的每个文档的确切 ID。所以我更喜欢“通过查询更新”,这样我就可以通过查询任何字段来更新文档。
  • 也许这个答案会有所帮助。 stackoverflow.com/a/53192844/3838328

标签: elasticsearch


【解决方案1】:

本示例使用 _update_by_query

POST indexname/type/_update_by_query
{
  "query": {
    "match": {
      "Title": "elasticsearch"
    }
  },
  "script": {
    "source": "ctx._source.Myfield1= params.mifieldAsParam",
    "params": {
      "mifieldAsParam": [
        {
          "nestfield1": "foo blabla...",
          "nestfield2": 100
        },
        {
          "nestfield1": "abc...",
          "nestfield2": 200
        }
      ]
    },
    "lang": "painless"
  }
}

【讨论】:

    【解决方案2】:

    嵌套元素需要在无痛脚本中迭代以更新值

    POST /index/_update_by_query
    {
      "script": {
        "source": "for(int i=0;i<=ctx._source['Myfield1'].size()-1;i++){ctx._source.Myfield1[i].field1='foo blabla...';ctx._source.Myfield1[i].field2=100}",
        "lang": "painless"
      },
      "query": {
         "match": {
            "Title": "elasticsearch"
         }
      }
    }
    

    如果索引已知,则嵌套元素值更新

    POST /index/_update_by_query
    {
      "script": {
        "source": "ctx._source.Myfield1[0].field1='foo blabla...';ctx._source.Myfield1[0].field2=100;ctx._source.Myfield1[1].field1='abc...';ctx._source.Myfield1[1].field2=200;",
        "lang": "painless"
      },
      "query": {
        "match": {
             "Title": "elasticsearch"
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      你可以试试params,像这样:

      "query" : {
          "match_all" : {}
      },
      "script" : "ctx._source.Myfield1 = Myfield1;",
      "params": {
        "Myfield1": {
          "nestfield1": "foo blabla..."
        }
      }
      

      在我的情况下,我将数据从嵌套字段中的非嵌套字段中移动。我需要添加虚假信息来初始化嵌套字段。看起来是这样的:

      "query" : {
          "match_all" : {}
      },
      "script" : "ctx._source.Myfield1 = Myfield1; ctx._source.Myfield1.nestfield1 = ctx._source.Myfield1Nestfield1;  ctx._source.Myfield1.nestfield2 = ctx._source.Myfield1Nestfield2;",
      "params": {
        "Myfield1": {
          "nestfield1": "init_data"
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-10
        • 1970-01-01
        • 2019-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多