ES中如何实现随机抽样查询 | 您所在的位置:网站首页 › 随机检索 › ES中如何实现随机抽样查询 |
一、场景说明
索引中有几千万的数据,现在需要每次查询随机抽样返回10条数据,怎么实现? 二、实现方式DSL语句执行如下: GET myIndex/_search { "from": 0, "size": 20, "timeout": "10s", "sort": { "_script": { "script": "Math.random()", "type": "number", "order": "asc" } } }java代码实现: private void randomSort(SearchSourceBuilder sourceBuilder){ Script script = new Script("Math.random()"); ScriptSortBuilder sortBuilder = new ScriptSortBuilder(script, ScriptSortBuilder.ScriptSortType.NUMBER); sourceBuilder.sort(sortBuilder); } 三、注意事项实际开发过程中发现,如果对索引中的全量数据进行随机抽样查询是非常消耗查询性能的。 我遇到的情况: 生产环境上,8千万多万数据的索引进行随机抽样查询耗时5s,这种查询速度显然是不能接受的。 优化改进: sort排序是针对匹配的所有数据进行排序,而8000多万数据的随机排序,显然非常耗时。 我们可以在查询条件中增加一些随机查询条件,比如主键id的随机前缀匹配,数据产生时间的随机范围匹配, 从而减轻随机匹配的性能损耗。 由于我的索引数据中id的前缀都是在0~9,所以我在每次查询时,先生成0~9的随机数,然后去匹配主键id做前缀匹配。 { "query": { "wildcard": { "id": { "value": "1*" } } } ,"sort":[{"_script":{"script":{"source":"Math.random()","lang":"painless"},"type":"number","order":"asc"}}] }
本文主要介绍了ES中如何实现随机抽样查询,并强调了随机抽样查询的性能损耗问题以及对应的解决方案。 |
CopyRight 2018-2019 实验室设备网 版权所有 |