从Elasticsearch文档中删除字段

Jal*_*lal 35 elasticsearch

我需要删除索引到Elasticsearch的所有文档中的字段.我该怎么做.是否有任何删除查询可以帮助我实现这一目标.

Vin*_*han 55

@backtrack说的是真的,但是在Elasticsearch中有一个非常方便的方法.Elasticsearch将抽象出删除的内部复杂性.您需要使用更新API来实现此目的 -

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.remove(\"name_of_field\")"
}'
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到更多文档.

注意:从弹性搜索6开始,您需要包含内容类型标题:

-H 'Content-Type: application/json'
Run Code Online (Sandbox Code Playgroud)

  • 如果您有 10 亿个包含该字段的文档,那么性能如何? (3认同)
  • @VineethMohan 它也会删除映射吗?所以如果我查询 test/type1/_mapping,它会显示“name_of_field”吗?所以基本上,我想删除并添加具有差异类型的相同文件名。这可能吗? (2认同)

spa*_*azm 27

Elasticsearch update_by_query在2.3中添加.此实验界面允许您对与查询匹配的所有文档进行更新.

内部elasticsearch执行扫描/滚动以收集批量文档,然后像批量更新界面一样更新它们.这比使用您自己的扫描/滚动界面手动操作更快,因为没有网络和序列化的开销.每条记录必须加载到ram中,修改后再写入.

昨天我从我的ES集群中删除了一个大字段.我在update_by_query期间看到了每秒10,000条记录的持续吞吐量,受CPU而不是IO的限制.

查看设置conflict=proceed群集是否具有其他更新流量,或者ConflictError当其中一个记录在其中一个批次下更新时,整个作业将在其到达时停止.

同样的设置wait_for_completion=false将导致update_by_query通过任务界面运行.否则,如果连接已关闭,作业将终止.

网址:

http://localhost:9200/INDEX/TYPE/_update_by_query?wait_for_completion=false&conflicts=proceed
Run Code Online (Sandbox Code Playgroud)

POST机构:

{
  "script": "ctx._source.remove('name_of_field')",
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field": "name_of_field"
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

从Elasticsearch 1.43开始,默认情况下禁用内联groovy脚本.您需要通过添加script.inline: true到配置文件来为这样的内联脚本启用它.

或者将groovy作为脚本上传并使用该"script": { "file": "scriptname", "lang": "groovy"}格式.

  • 身体需要稍作修改,但除此之外它完美无缺.我不得不将脚本包装在JSON对象中,可能是因为API发生了一些变化. (2认同)

小智 12

以前的答案对我不起作用。

我不得不添加关键字“内联”:

POST /my_index/_update_by_query
{
  "script": {
    "inline": "ctx._source.remove(\"myfield\")"
  },
  "query" : {
      "exists": { "field": "myfield" }
  }
}
Run Code Online (Sandbox Code Playgroud)


Thi*_*cao 9

您可以使用_update_by_query

例子1

索引:my_index

字段:user.email

POST my_index/_update_by_query?conflicts=proceed
{
    "script" : "ctx._source.user.remove('email')",
    "query" : {
        "exists": { "field": "user.email" }
    }
}
Run Code Online (Sandbox Code Playgroud)

例子2

索引:my_index

栏位:total_items

POST my_index/_update_by_query?conflicts=proceed
{
    "script" : "ctx._source.remove('total_items')",
    "query" : {
        "exists": { "field": "total_items" }
    }
}
Run Code Online (Sandbox Code Playgroud)


bac*_*ack 7

默认情况下,这是不可能的,因为现在Lucene不支持这一点.基本上你只能从Lucene索引中放入或删除整个Lucene文档.

  1. 获取您的文档的第一个版本
  2. 删除该字段
  3. 推送这个新版本的文档

  • elasticsearch为您解决这个问题。 (2认同)
  • @ThomasDecaux,非常感谢。我在2015年回答过,我知道ES现在已经具备了这种能力。再次感谢您为它加油。 (2认同)