Elasticsearch如何查询category_id值存在于categories数组字段中的文档
错误原因
你编写的DSL无法生效的核心原因有两点:
- terms查询的右侧值默认是静态常量,你填入的
doc.categories会被识别为普通字符串,不会动态读取当前文档的categories字段内容做匹配 - 你的
category_id是字符串类型,categories数组存储的是数值类型,直接匹配会因为类型不一致返回false
正确实现方案
使用Painless脚本查询实现同文档内字段的动态匹配,示例DSL如下:
{ "query": { "bool": { "filter": [ { "script": { "script": { "lang": "painless", "source": "doc['categories'].contains(Integer.parseInt(doc['category_id'].value))" } } } ] } } }
如果你的文档存在category_id为空、categories为空的场景,可以扩展脚本逻辑避免执行异常:
{ "query": { "bool": { "filter": [ { "script": { "script": { "lang": "painless", "source": "doc.containsKey('category_id') && doc.containsKey('categories') && !doc['category_id'].empty && !doc['categories'].empty && doc['categories'].contains(Integer.parseInt(doc['category_id'].value))" } } } ] } } }
说明:将查询逻辑放在filter上下文而非must上下文,不会参与相关性算分,查询性能更高。
性能优化建议
如果这个查询是高频使用的场景,建议在写入数据时提前计算新增一个category_match布尔字段,写入时直接判断category_id是否在categories数组中并赋值,查询时直接匹配该布尔字段即可,性能远高于实时脚本计算。
内容的提问来源于stack exchange,提问作者Farhad Mohammadi
相关产品推荐
相关产品推荐

