Elasticsearch如何无需指定ads下标查询两种结构的ads字段内容
解决方案
你的场景本质是ads字段在ES索引中存在两种映射类型:部分文档为数字键命名的嵌套对象,部分文档为对象数组,以下DSL可以同时兼容两种结构,无需指定固定下标:
GET car/_search { "query": { "bool": { "filter": [ // 筛选status=1,filter不参与算分性能更优 {"term": {"status": 1}}, { "bool": { "minimum_should_match": 1, "should": [ // 适配ads为对象数组的场景 {"term": {"ads.city_id": 83}}, // 适配ads为数字键嵌套对象的场景,通配符匹配任意下标 {"term": {"ads.*.city_id": 83}} ] } } ] } } }
如果你的实际查询字段为ads.city.slug,将上述DSL中的字段名对应替换为ads.city.slug、ads.*.city.slug即可。
低版本ES兼容方案
如果你使用的ES版本低于7.10,通配符字段查询默认未开启,可以替换为query_string实现相同效果:
GET car/_search { "query": { "bool": { "filter": [ {"term": {"status": 1}}, { "bool": { "minimum_should_match": 1, "should": [ {"term": {"ads.city_id": 83}}, { "query_string": { "default_field": "ads.*.city_id", "query": "83" } } ] } } ] } } }
长期优化建议
字段类型不一致会大幅提升查询复杂度、降低检索性能,建议后续做如下优化:
- 写入数据时统一
ads字段结构为对象数组,避免使用数字键作为属性名的嵌套对象 - 提前为索引设置固定mapping,关闭动态映射自动推导字段类型的逻辑,避免出现同名字段类型不一致的问题
内容的提问来源于stack exchange,提问作者Hamidreza
相关产品推荐
相关产品推荐

