从Elasticsearch文档中删除字段

时间:2015-03-12 05:03:54

标签: elasticsearch

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

7 个答案:

答案 0 :(得分:46)

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

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

您可以找到更多文档here

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

-H 'Content-Type: application/json'

答案 1 :(得分:23)

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

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

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

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

同样设置wait_for_completion=false将导致update_by_query通过tasks接口运行。否则,如果连接关闭,作业将终止。

URL:

http://localhost:9200/INDEX/TYPE/_update_by_query?wait_for_completion=false&conflicts=proceed

POST正文:

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

从Elasticsearch 1.43开始,内联groovy scripting is disabled by default。您需要通过将script.inline: true添加到配置文件来为此类内联脚本启用它。

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

答案 2 :(得分:6)

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

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

答案 3 :(得分:5)

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

我必须添加关键字“内联”:

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

答案 4 :(得分:4)

您可以使用 _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" }
    }
}

示例2

索引:my_index

字段:total_items

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

答案 5 :(得分:0)

对于那些坚持使用bulk API的人来说,实现删除文档字段的另一种方法是在批量API调用的update action payload中提供额外的脚本。

命令部分与官方文档中描述的相同:

curl -s -H "Content-Type: application/x-ndjson"  -H "Accept: application/json; indent=4;" \
     --data-binary   '@es_bulk_edit_data.json'  --request POST \
     "http://YOUR_ELASTICSEARCH_HOST:PORT_NUM/OPTIONAL_INDEX/OPTIONAL_TYPE/_bulk?pretty"

在请求正文文件中,您可能需要为同一文档使用2个有效负载,其中一个有效负载用于创建,更新字段,另一个有效负载用于通过脚本删除字段,如下所示:

// assume you attempt to add one field `artist`, update one field `num_views`,
// and delete one field `useless` in the document with type t1 and ID 123
{"update": {"_type": "t1", "_id": "123"}}
{"doc": {"artist": "new_artist", "num_views": 67}}
{"update": {"_type": "t1", "_id": "123"}}
{"script": {"source": "ctx._source.remove(params.del_field_name)", "lang":"painless", "params":{"del_field_name": "useless"}}}

注意:

  • 在批量API中,doc部分不能与script部分放在同一有效负载中,ElasticSearch似乎拒绝处理这种有效负载结构并返回错误响应400 bad request,并且原因消息会是Validation Failed: 1: can't provide both script and doc;。这就是为什么我将删除和所有其他操作分别放在2个有效载荷中的原因。
  • 这些已在5.6和6.6版上进行了测试,在最新版本(v7.10)中也应获得相同的结果

答案 6 :(得分:0)

PUT /products/_update/1
{
  "docs" :{
    "price": 12,
    "quantity": 3,
    "in_stock": 6
  }
}

Now if I need to remove "quantity" then:

POST products/_update/1
{
  "script": {
    "source": "ctx._source.remove(\"quantity\")"
  }
}