我需要在所有索引到 Elasticsearch 的文档中删除一个字段。该如何操作?
我需要在所有索引到 Elasticsearch 的文档中删除一个字段。该如何操作?
@backtrack所说的是正确的,但是在Elasticsearch中有一种非常方便的方法来完成这个操作。 Elasticsearch将抽象出删除的内部复杂性。 您需要使用Update API来实现此目的 -
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.remove(\"name_of_field\")"
}'
您可以在此处找到更多文档。
注意:自Elastic Search 6版本起,您需要包含一个content-type头。
-H 'Content-Type: application/json'
ctx._source[\"my-field\"].remove(\"subfield\")
。 - Martin FootElasticsearch在2.3版本中添加了update_by_query
。这个实验接口允许你针对匹配查询的所有文档进行更新。
内部elasticsearch执行扫描/滚动以收集文档批次,然后像批量更新界面一样更新它们。这比使用自己的扫描/滚动界面手动执行更快,因为没有网络和序列化开销。每条记录必须加载到RAM中,修改后写入。
昨天我从我的ES集群中删除了一个大字段。在update_by_query期间,我看到持续的每秒10,000条记录吞吐量,受CPU限制而不是IO。
如果集群有其他更新流量,或者当其中一个记录在批处理之一下更新时,会出现ConflictError
,则需要设置conflicts=proceed
。否则整个作业将停止。
同样,设置wait_for_completion=false
将导致update_by_query通过tasks接口运行。否则,如果连接关闭,作业将终止。
url:
http://localhost:9200/INDEX/TYPE/_update_by_query?wait_for_completion=false&conflicts=proceed
请求正文:
{
"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
索引:my_index
字段:user.email
POST my_index/_update_by_query?conflicts=proceed
{
"script" : "ctx._source.user.remove('email')",
"query" : {
"exists": { "field": "user.email" }
}
}
索引: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?conflicts=proceed
{
"script" : "ctx._source.A.remove('B')",
"query" : {
"exists": { "field": "A.B" }
}
}
如果它不能工作,您需要使用正确的映射将目标索引重新索引数据。 - Thiago Falcao之前的答案对我没有用。
我不得不添加关键字"inline":
POST /my_index/_update_by_query
{
"script": {
"inline": "ctx._source.remove(\"myfield\")"
},
"query" : {
"exists": { "field": "myfield" }
}
}
默认情况下,这是不可能的,因为现在的Lucene不支持这样做。基本上,你只能将整个Lucene文档放入或从Lucene索引中删除。
这个答案适用于ES 5版本以下。
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\")"
}
}
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
"source": {
"index": "old-index"
},
"dest": {
"index": "new-index"
}}
'
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"
// 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"}}}
注意:
doc
部分不能与script
部分放置在同一个有效载荷中,ElasticSearch似乎拒绝处理这种有效载荷结构并返回错误响应400 bad request
,原因消息将是Validation Failed: 1: can't provide both script and doc;
。这就是为什么我将删除和所有其他操作分成2个有效载荷的原因。