繁体   English   中英

从 Elasticsearch 文档中删除一个字段

[英]Remove a field from a Elasticsearch document

我需要删除索引为 Elasticsearch 的所有文档中的一个字段。我该怎么做?

@backtrack 所说的是真的,但是在 Elasticsearch 中有一种非常方便的方法可以做到这一点。 Elasticsearch 会抽象出删除的内部复杂性。 您需要使用更新 API 来实现这一点 -

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

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

注意:从 Elastic Search 6 开始,您需要包含一个内容类型标头:

-H 'Content-Type: application/json'

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

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

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

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

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

网址:

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 脚本 您需要通过将script.inline: true添加到您的配置文件来为这样的内联脚本启用它。

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

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

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

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

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

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

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

此答案适用于版本 < ES 5。

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

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

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个payload,一个用于创建、更新字段,另一个用于通过脚本删除字段,可能是这样的:

// 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) 中也应该得到相同的结果
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\")"
  }
}

我想补充一下之前的答案,删除字段后,索引的大小不会改变 将不得不创建一个新索引或使用 _reindex api。

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
 "source": {
   "index": "old-index"
 },
 "dest": {
   "index": "new-index"
}}

'

要删除索引为 Elasticsearch 的所有文档中的字段,您可以使用_update_by_query 这允许您通过指定与要更新的文档相匹配的查询来一次更新多个文档。 您可以使用脚本参数来指定将从文档中删除该字段的脚本。

您可以使用以下语法从所有文档中删除名为 field_name 的字段:

POST _update_by_query
{
  "script": {
    "source": "ctx._source.remove('field_name')"
  }
}

您还可以在查询中指定索引、类型和过滤器以进行更具体的更新。

在整个数据集上运行脚本之前,先在一小部分文档上测试脚本始终是个好主意。 此外,请记住,通过查询 API 进行的更新可能会占用大量资源,并且可能需要一些时间才能完成,具体取决于数据集的大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM