Elasticsearch如何实现hits字段与inner_hits嵌套字段的乘法计算
解决方案
你可以通过 script_fields 或者运行时字段(Runtime Field)在Elasticsearch查询阶段直接完成两个字段的乘法计算,无需在业务侧二次处理,以下是具体实现:
方案1:script_fields实现(兼容ES7.x及以上所有版本)
在原有查询基础上新增script_fields配置,脚本会自动匹配对应guid的嵌套sizes文档,取出ratio后和根层级的cost相乘:
{ "query": { "nested": { "path": "sizes", "query": { "bool": { "must": [ { "match": { "sizes.guid": "dhsfsfgs-c099-4c83-abbc-cc45a2ecaa46" } } ] } }, "inner_hits": {} } }, "script_fields": { "calculated_cost": { "script": { "lang": "painless", "params": { "target_guid": "dhsfsfgs-c099-4c83-abbc-cc45a2ecaa46" }, "source": """ for (def size : params._source.sizes) { if (size.guid == params.target_guid) { return params._source.cost * size.ratio; } } return 0; """ } } } }
查询返回结果中会新增fields节点,其中calculated_cost就是你需要的乘积结果。如果需要同时返回原始文档数据,可新增配置"_source": true。
方案2:Runtime Field实现(支持ES7.11及以上版本)
你也可以在查询时临时定义运行时字段,该字段可直接用于后续的查询、聚合逻辑:
{ "runtime_mappings": { "calculated_cost": { "type": "double", "script": { "lang": "painless", "params": { "target_guid": "dhsfsfgs-c099-4c83-abbc-cc45a2ecaa46" }, "source": """ for (def size : params._source.sizes) { if (size.guid == params.target_guid) { emit(params._source.cost * size.ratio); return; } } emit(0.0); """ } } }, "query": { "nested": { "path": "sizes", "query": { "bool": { "must": [ { "match": { "sizes.guid": "dhsfsfgs-c099-4c83-abbc-cc45a2ecaa46" } } ] } }, "inner_hits": {} } }, "fields": ["calculated_cost"] }
内容的提问来源于stack exchange,提问作者Ranjith kumar
相关产品推荐
相关产品推荐

