Elasticsearch条件查询需求:relation为3时排除level1/level2字段
Elasticsearch动态排除字段需求解决方案
问题背景
我有如下格式的Elasticsearch文档:
{ "demo":{ "sample1":"", "sample2":"" }, "hier":{ "level10":"123", "level9":"456", "level8":"789", "level7":"012", "level6":"234", "level5":"345", "level2":"567", "level1":"678", "relation":3 } }
这些文档存储企业完整层级结构,需求是:当hier.relation等于3时,从查询结果中移除hier.level1和hier.level2字段;其他情况返回完整字段。
我之前尝试的查询无法实现该逻辑:
{ "from":0, "size":100, "query":{ "bool":{ "must":[ { "multi_match":{ // 用于获取完整层级的查询 } } ], "must_not":[ { "match":{ "hier.level1": "" } }, { "match":{ "hier.level2": "" } } ] } } }
原查询用must_not过滤掉包含空值字段的文档,和需求逻辑完全不符,需要调整。
正确实现方案
方法1:使用_source脚本动态控制返回字段(推荐)
通过_source的脚本判断hier.relation的值,动态决定是否排除指定字段:
{ "from": 0, "size": 100, "query": { "bool": { "must": [ // 保留你原本的查询条件,比如multi_match { "multi_match": { // 此处填写你的查询配置,例如"query": "xxx", "fields": ["*"] } } ] } }, "_source": { "script": { "source": """ if (doc['hier.relation'].value == 3) { // 返回所有字段,排除hier.level1和hier.level2 return ['*', '!hier.level1', '!hier.level2']; } else { // 返回全部字段 return ['*']; } """ } } }
- 注意:确保
hier.relation字段是数值类型(如integer),如果是文本类型,需将判断条件改为doc['hier.relation'].value == '3'。
方法2:使用script_fields重构hier字段
如果需要更精细的字段控制,可以单独重构hier字段:
{ "from": 0, "size": 100, "query": { "bool": { "must": [ // 你的查询条件 { "multi_match": { // 查询配置 } } ] } }, "_source": ["demo"], // 直接返回非hier的字段 "script_fields": { "hier": { "script": { "source": """ def hierMap = params._source.hier; if (hierMap.relation == 3) { hierMap.remove('level1'); hierMap.remove('level2'); } return hierMap; """ } } } }
- 逻辑:先指定返回
demo字段,再通过脚本处理hier字段,满足条件时移除目标字段后返回。
内容的提问来源于stack exchange,提问作者Anvesh Reddy
相关产品推荐
相关产品推荐

