能否构建ElasticSearch查询仅返回匹配条件的嵌套对象而非全部?
实现仅返回符合条件的嵌套对象
当然可以做到!不过这里有个核心前提:你的available字段必须定义为nested类型,而非ES默认的object类型。因为默认的object类型会把数组里的所有嵌套对象扁平化存储,导致无法精准过滤出单独匹配的元素——你可能会搜到符合条件的文档,但返回的还是整个available数组。
步骤1:创建正确的索引映射
首先得确保你的索引映射把available设为nested类型,这样每个嵌套对象会被当作独立的"子文档"存储,才能单独匹配和返回。示例代码如下:
PUT /shoes { "mappings": { "properties": { "product": { "type": "text" }, "available": { "type": "nested", "properties": { "size": { "type": "keyword" }, "color": { "type": "keyword" } } } } } }
步骤2:编写带inner_hits的嵌套查询
接下来就可以编写查询,用nested查询定位到符合条件的嵌套对象,同时通过inner_hits返回这些匹配的对象(而不是整个数组)。示例查询如下:
POST /shoes/_search { "_source": ["product"], // 只返回product字段,避免带出完整的available数组 "query": { "nested": { "path": "available", // 指定嵌套字段的路径 "query": { "match": { "available.color": "red" } // 匹配颜色为red的条件 }, "inner_hits": { "_source": ["size", "color"] // 可选:只返回嵌套对象的指定字段 } } } }
查询结果说明
执行上面的查询后,返回的每个命中文档会包含inner_hits字段,里面就是符合条件的available元素。典型的返回结构如下:
{ "hits": { "hits": [ { "_source": { "product": "shoe 1" }, "inner_hits": { "available": { "hits": { "hits": [ { "_source": { "size": "small", "color": "red" } } ] } } } }, { "_source": { "product": "shoe 2" }, "inner_hits": { "available": { "hits": { "hits": [ { "_source": { "size": "medium", "color": "red" } } ] } } } } ] } }
调整为你期望的输出结构
ES本身不会直接修改原始文档的结构返回(比如把available数组替换为匹配的元素),但你可以在客户端做简单的处理:把每个文档的_source.available设置为inner_hits.available.hits.hits中的_source数组,就能得到你想要的格式。
另外要注意:如果你的现有索引已经把available设为object类型,无法直接修改字段类型,需要重新创建索引并重新导入数据。
内容的提问来源于stack exchange,提问作者Davout
相关产品推荐
相关产品推荐

