如何更新elasticsearch中数组中的元素?

问题描述 投票:0回答:1

我有一个索引,其中一个字段是对象列表。我不能让每个字段都有自己的字段,否则字段的数量会爆炸。

文档的更新作为添加或更新列表中对象之一的项目出现。我该如何制作更新来实现这一目标?

elasticsearch elasticsearch-painless
1个回答
0
投票

您可以使用脚本和 update_by_query 来完成此操作。

让我们创建一个索引:

PUT test-index/_doc/1
{
  "id": 3
}

新的子文档出现后,我们希望它看起来像这样:

GET test-index/_doc/1

返回:

{
  "id": 1,
  "items": [{
    "id": "q1",
    "colour": "brown"
  }]
}

我们可以通过存储以下脚本然后调用它来做到这一点:

POST _scripts/upsert_item_in_list
{
  "script":{  
    "lang": "painless", 
    "source": """
    if (ctx._source[params.field] == null) {
      ctx._source[params.field] = [];
    }
    def items = ctx._source[params.field];
    def index = -1;
    for (int i = 0; i < items.length; i++)
    { 
        if (items[i][key] == params.item[params.key]) 
        {
          index = i
        } 
    }
   if (index>=0) {
     items[index] = params.item;
   } else {
     items.add(params.item)
   }
    """
  }
}

它需要三个参数:

  • 数组所在字段的名称
  • 数组项中唯一键字段的名称
  • 要存储的值。

我们可以按如下方式调用它:

POST test-index/_update_by_query
{
  "script":{  
    "params": {
      "item": { "id": "q1", "colour": "brown" }
      "field": "items",
      "key": "id"
    },
    "id": "upsert_item_in_list"
  },
  "query":{
    "match":{
      "id": 1
    } 
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.