如何基于Elasticsearch另一索引的字段值更新指定索引对应字段
方案1:一次性快速更新(适合indexB数据量极小的场景)
因为indexB仅10条数据,你可以先把所有product_name和product_desc的映射关系提取出来,直接用painless脚本批量更新indexA,操作最简单:
- 先查询indexB全量数据,提取映射关系:
GET index_B/_search?size=100
你会得到类似如下的映射:{"EES":"Elastic Enterprise Search", "EO":"Elastic Observability"}
2. 执行批量更新命令,将映射填入脚本中:
POST index_A/_update_by_query { "query": { "bool": { "must_not": [ {"exists": {"field": "product_desc"}} ] } }, "script": { "lang": "painless", "source": """ // 替换为你自己的indexB映射数据 Map descMap = [ "EES": "Elastic Enterprise Search", "EO": "Elastic Observability" ]; if (ctx._source.product_name != null && descMap.containsKey(ctx._source.product_name)) { ctx._source.product_desc = descMap.get(ctx._source.product_name); } """ } }
10K条数据仅需几秒即可跑完,must_not条件会自动跳过已经存在product_desc的文档,避免重复执行产生问题。
方案2:长期自动化更新(适合有增量写入需求的场景)
如果后续indexA还有持续的新数据写入,或者indexB的映射会定期更新,可以用ES原生的Enrich处理器实现自动化关联:
- 创建Enrich策略,绑定indexB的关联规则:
PUT /_enrich/policy/product_desc_policy { "match": { "indices": "index_B", "match_field": "product_name", "enrich_fields": ["product_desc"] } }
- 执行策略,将indexB的映射加载到内存的专属enrich索引中:
POST /_enrich/policy/product_desc_policy/_execute
后续如果indexB的内容更新,重新执行该命令即可刷新映射关系
- 创建数据处理管道,实现自动关联赋值:
PUT _ingest/pipeline/add_product_desc_pipeline { "processors": [ { "enrich": { "policy": "product_desc_policy", "field": "product_name", "target_field": "tmp_enrich_data", "ignore_missing": true, "ignore_failure": true } }, { "set": { "field": "product_desc", "value": "{{tmp_enrich_data.product_desc}}", "ignore_empty_value": true, "override": false } }, { "remove": { "field": "tmp_enrich_data", "ignore_missing": true } } ] }
- 批量更新存量的indexA数据:
POST index_A/_update_by_query?pipeline=add_product_desc_pipeline { "query": { "bool": { "must_not": [ {"exists": {"field": "product_desc"}} ] } } }
- (可选)配置indexA默认管道,后续新写入的文档自动补充
product_desc字段:
PUT index_A/_settings { "index.default_pipeline": "add_product_desc_pipeline" }
内容的提问来源于stack exchange,提问作者Sandeep Kanabar
相关产品推荐
相关产品推荐

