Elasticsearch如何按条件过滤响应中labels字段的返回内容
Elasticsearch 按条件过滤数组字段返回结果实现方案
_source配置项的include/exclude规则仅支持字段粒度的黑白名单筛选,无法对数组类型字段内部的元素做条件匹配过滤,要实现仅保留labels字段中key为pool-id的键值对,可通过以下两种方式实现:
方案1:脚本字段(兼容全版本ES)
无需修改索引结构,直接在查询阶段通过Painless脚本过滤数组元素,查询语句如下:
GET /houseId/_search { "_source": ["name"], "script_fields": { "labels": { "script": { "lang": "painless", "source": """ // 查找labels中key为pool-id的第一个匹配项 return params._source.labels.find(label -> label.key == 'pool-id'); """ } } }, "query": { "bool": { "must": [ { "terms": { "cloud_id.keyword": ["something"] } } ] } } }
若存在文档无对应
pool-id标签的场景,可在脚本中增加判空逻辑,自定义无匹配时的返回值。
该查询返回的labels字段为单个对象,完全匹配预期结构,不会返回key为active的冗余数据。
方案2:运行时字段(ES 7.12+ 版本推荐)
7.12及以上版本支持运行时字段,逻辑解耦更清晰,复用性更强:
GET /houseId/_search { "runtime_mappings": { "labels": { "type": "object", "script": { "source": """ for(def label : params._source.labels) { if(label.key == 'pool-id') { // 匹配到目标标签后返回对应key、value emit(label.key, label.value); break; } } """ } } }, "_source": ["name"], "fields": ["labels"], "query": { "bool": { "must": [ { "terms": { "cloud_id.keyword": ["something"] } } ] } } }
- 上述两种方案均不会修改索引内存储的原始数据,仅调整查询返回的结果结构
- 若该查询调用频率很高、对性能要求严苛,建议在数据写入阶段提前做字段拆分,将
pool-id对应的标签值单独存储为独立字段,查询时直接通过_source返回即可,避免运行时脚本的计算开销
内容的提问来源于stack exchange,提问作者Atul
相关产品推荐
相关产品推荐

