Elasticsearch如何筛选指定语言字段与全局字段返回?
解决方案
你的问题出在_source的包含排除逻辑:Elasticsearch会先应用includes规则,再执行excludes,所以你先包含了所有字段和指定语言字段,随后的excludes: ["lng:*"]会把所有语言字段(包括你要保留的lng:en_AE:*)都过滤掉,导致结果不符合预期。
由于无法预知所有语言前缀且不能修改索引结构,推荐使用Painless响应脚本直接过滤返回字段,具体实现如下:
{ "query": { "match_all": {} // 替换为你的实际查询条件 }, "_source": true, "script": { "source": """ // 收集需要保留的字段:全局字段(非lng开头)+ 指定语言字段 def keepFields = new HashSet(); for (def field : ctx._source.keySet()) { if (!field.startsWith('lng:') || field.startsWith('lng:en_AE:')) { keepFields.add(field); } } // 删除不需要的字段 def keysToRemove = new ArrayList(); for (def field : ctx._source.keySet()) { if (!keepFields.contains(field)) { keysToRemove.add(field); } } for (def key : keysToRemove) { ctx._source.remove(key); } """, "lang": "painless" } }
脚本说明
- 遍历
_source的所有字段,将非lng:开头的全局字段和以lng:en_AE:开头的目标语言字段加入保留集合 - 反向收集需要删除的字段(不在保留集合中的字段)
- 从
_source中移除这些不需要的字段,最终只返回你需要的内容
注意事项
- 确保Elasticsearch集群允许使用Painless脚本(默认开启,若有权限限制需调整
elasticsearch.yml中的脚本配置) - 脚本会对每条命中的文档执行,若查询结果量较大,可能存在轻微性能损耗,建议根据实际场景评估
内容的提问来源于stack exchange,提问作者ItayB
相关产品推荐
相关产品推荐

