替代lookup数据类型:如何在索引层面实现字段关联填充?
实现索引层面的字段填充方案
你用runtime mappings的lookup类型只能在查询时临时生成字段,不会将数据持久化到索引中。要实现索引层面的字段填充(即将描述字段写入文档本身),可以通过以下几种方式实现:
方式一:用Update By Query批量更新现有文档
直接对input_index中的所有文档执行更新操作,查询lookup_index获取对应描述并写入新字段input_desc:
POST input_index/_update_by_query { "script": { "source": """ // 查询lookup索引中匹配input_code的文档 def lookupResp = ctx._index.getSearcher().search(new org.elasticsearch.index.query.TermQueryBuilder("lookup_code", ctx._source.input_code), 1); if (lookupResp.getHits().getHits().length > 0) { // 将匹配到的描述写入input_desc字段 ctx._source.input_desc = lookupResp.getHits().getAt(0).getSourceAsMap().get("lookup_desc"); } else { // 无匹配时设置默认值 ctx._source.input_desc = "N/A"; } """, "lang": "painless" } }
注意事项
- 确保执行操作的用户拥有
input_index的写入权限和lookup_index的读取权限 - 若数据量较大,可添加
size参数分批执行,避免集群性能压力 - 脚本中使用的Elasticsearch内部类需对应你使用的ES版本,若报错可调整类路径
方式二:用Reindex API迁移并填充数据
如果希望保留原索引,可将数据重索引到新索引,同时在迁移过程中填充描述字段:
- 先创建目标索引(需提前定义好
input_desc字段的映射,比如设为text或keyword):
PUT input_index_with_desc { "mappings": { "properties": { "input_code": {"type": "keyword"}, "input_desc": {"type": "text"} } } }
- 执行重索引并填充字段:
POST _reindex { "source": { "index": "input_index" }, "dest": { "index": "input_index_with_desc" }, "script": { "source": """ def lookupResp = ctx._index.getSearcher().search(new org.elasticsearch.index.query.TermQueryBuilder("lookup_code", ctx._source.input_code), 1); if (lookupResp.getHits().getHits().length > 0) { ctx._source.input_desc = lookupResp.getHits().getAt(0).getSourceAsMap().get("lookup_desc"); } else { ctx._source.input_desc = "N/A"; } """, "lang": "painless" } }
- (可选)若要替换原索引,可删除原索引后将新索引别名设为原索引名:
DELETE input_index PUT input_index/_alias/input_index_with_desc
方式三:用Ingest Pipeline处理新写入的数据
如果后续还有新数据写入input_index,可以创建 ingestion pipeline,在数据写入时自动查询lookup_index填充描述字段:
- 创建pipeline:
PUT _ingest/pipeline/add_lookup_desc { "processors": [ { "script": { "source": """ def client = ctx._ingest.client; // 查询lookup索引匹配的文档 def response = client.search({ index: 'lookup_index', query: { term: { lookup_code: ctx.input_code } }, size: 1 }); if (response.hits.hits.length > 0) { ctx.input_desc = response.hits.hits[0]._source.lookup_desc; } else { ctx.input_desc = "N/A"; } """, "lang": "painless" } } ] }
- 设置
input_index的默认pipeline,后续所有写入数据都会自动填充字段:
PUT input_index/_settings { "index.default_pipeline": "add_lookup_desc" }
- 手动写入数据时也可指定pipeline(若未设置默认):
POST input_index/_doc/1?pipeline=add_lookup_desc { "input_code": "your_code_here" }
内容的提问来源于stack exchange,提问作者hrishi
相关产品推荐
相关产品推荐

