ES踩了一坑 script查询与float类型的精度
今天ES需要查询一个比例的计算, 逻辑也简单, 就是: receivableAmount➗invoiceMoney ✖️100%
使用_doc查询id时, 可以看到receivableAmount 值为6.38, invoiceMoney 值为 10, 结果一目了然是63.8%
但是输入区间查询时, 怎么查也查不出来, 震惊整个小组!!!
查询json如下:
{"query": {"bool": {"must": [{"script": {"script": {"source": "try { if (doc.containsKey('receivableAmount') && doc.containsKey('invoiceMoney')) { double ra = (doc['receivableAmount'].value)*1.00; double im = doc['invoiceMoney'].value; if(im <= 0){return false;} double rate = ra / im * 100; return rate >= params.minRatio&&rate<params.maxRatio; } return false;} catch (Exception e) { return false;}","params": {"minRatio": 63.795,"maxRatio": 63.804}}}}]}}}
百思不得其解之下, 我试着把运算过程中的值都打印一下, 你猜怎么着?
查询json:
{"query": {"bool": {"must": [{"script": {"script": {"source": "try { if (doc.containsKey('receivableAmount') && doc.containsKey('invoiceMoney')) { double ra = (doc['receivableAmount'].value)*1.00; double im = doc['invoiceMoney'].value; if(im <= 0){return false;} double rate = ra / im * 100; return rate >= 0; } return false;} catch (Exception e) { return false;}","params": {"minRatio": 63.795,"maxRatio": 63.804}}}}]}},"script_fields": {"calculated_ratio": {"script": {"source": "if (doc['invoiceMoney'].size() == 0 || doc['invoiceMoney'].value == 0) return -1; return (doc['receivableAmount'].value / doc['invoiceMoney'].value) * 100.00;"}},"receivableAmount": {"script": {"source": "return doc['receivableAmount'].value;"}},"invoiceMoney": {"script": {"source": "return doc['invoiceMoney'].value;"}}}}
receivableAmount 在实际运算过程中, 它值居然是 6 ?! wtf, 和我们_doc查询时看到的完全是两码事!
接着, 我去看了一下索引的映射信息, 发现有个同事搞错了, 它的字段精度是1
"receivableAmount": {"type": "scaled_float","scaling_factor": 1
}
呵呵, 无语得我想笑…
啥也不说了, 调整字段类型, 重建索引吧.
这也是ES埋得比较深的坑之一.
