Elasticsearch数组多条件精准匹配查询问题求解
问题根因
Elasticsearch默认存储普通对象数组时,会将数组内所有对象的同名字段打散合并为扁平化数组,不会保留单个对象内部的字段关联关系。你的现有查询只会检查features数组中是否存在color为black的元素、是否存在memory为64GB的元素,不要求两个属性属于同一个对象,因此会出现误匹配。
解决步骤
步骤1:调整索引mapping,将features字段设置为nested类型
nested是ES专门用于保留对象数组内部字段关联的特殊类型,每个nested对象会被当作独立的隐藏文档存储,查询时可针对单个nested对象做多条件联合匹配。
如果是新建索引,mapping配置如下:
PUT /你的索引名称 { "mappings": { "properties": { "product_name": { "type": "keyword" }, "features": { "type": "nested", "properties": { "color": {"type": "keyword"}, "memory": {"type": "keyword"} } } } } }
注意:如果已经存在旧索引,无法直接修改已有字段类型,需要重建索引并重新导入数据才能生效。
步骤2:编写符合要求的查询语句
DSL查询(推荐,可读性和灵活性更高)
POST /你的索引名称/_search { "query": { "bool": { "must": [ { "term": { "product_name": "iPhone 9" } }, { "nested": { "path": "features", "query": { "bool": { "must": [ {"term": {"features.color": "black"}}, {"term": {"features.memory": "64GB"}} ] } } } } ] } } }
提示:如果product_name是text分词类型,可将上述
term查询改为match_phrase保证精确匹配。
轻量URI查询写法
_search?q=product_name:"iPhone 9" AND features:{color:"black" AND memory:"64GB"}
该语法是ES针对nested类型提供的URI查询支持,花括号内的条件会要求同时命中同一个nested对象的字段。
内容的提问来源于stack exchange,提问作者Techie Boy
相关产品推荐
相关产品推荐

