当使用es分页查询的时候,如果查询的数据太靠后了,就会产生深度分页问题。
假设es有3个节点,node1,node2,node3
查询 limti 50000,50
假设请求的是node1,此时会在每个节点上抓出 50050条数据,然后在node1汇总排序,取出50条数据。此时就发生了深度分页问题。es在2.0之后有个配置参数max_result_window限制了深度分页最大是10000。
查询的是实时的数据,但是每次查询需要带上上一次查询的最后一个sort值。并且需要文档中有一个字段保存唯一值,一般就用uuid来填充了。
所以在查询的时候需要一页一页的查询下去,因为需要拿到上一次的sort值,如果一次性查询 limit 20000,20还是不行的,需要从第一页开始查询下去。
请求demo
文档中的uid属性是唯一的
GET /student/student/_search
{"query":{"match_all": {}},"size":2,"sort":[{"uid": "desc"}]
}
结果demo,结果集中有sort字段,下一次的search_after查询需要带上此次最后一条记录的sort的值
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 5,"successful" : 5,"skipped" : 0,"failed" : 0},"hits" : {"total" : 6,"max_score" : null,"hits" : [{"_index" : "student","_type" : "student","_id" : "6","_score" : null,"_source" : {"uid" : 1006,"name" : "dehua","age" : 27,"class" : "3-1"},"sort" : [1006]},{"_index" : "student","_type" : "student","_id" : "5","_score" : null,"_source" : {"uid" : 1005,"name" : "fucheng","age" : 23,"class" : "2-3"},"sort" : [1005]}]}
}
下一次的search_after查询
GET /student/student/_search
{"query":{"match_all": {}},"size":2,"search_after":[1005],"sort":[{"uid": "desc"}]
}
适合大数据量的一次性查询
类似mysql的游标查询,在查询的时候生成一个快照,然后不断的分批从快照中获取数据,可以设置这个快照的过期时间。此时文档数据被修改是不会同步给快照中的数据的。
请求demo
GET /student/student/_search
{"query":{"match_all": {}},"size":2,"search_after":[1005],"sort":[{"uid": "desc"}]
}
第一次响应的数据中有_scroll_id字段,后面的scroll查询都要带上这个字段
{"_scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAC0YFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtGRZpZVI1dUEyMlNuVzBwU3JNVzR6RVlBAAAAAAAALRsWaWVSNXVBMjJTblcwcFNyTVc0ekVZQQAAAAAAAC0aFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtHBZpZVI1dUEyMlNuVzBwU3JNVzR6RVlB","took" : 0,"timed_out" : false,"_shards" : {"total" : 5,"successful" : 5,"skipped" : 0,"failed" : 0},"hits" : {"total" : 6,"max_score" : 1.0,"hits" : [{"_index" : "student","_type" : "student","_id" : "5","_score" : 1.0,"_source" : {"name" : "fucheng","age" : 23,"class" : "2-3"}},{"_index" : "student","_type" : "student","_id" : "2","_score" : 1.0,"_source" : {"name" : "xiaoming","age" : 25,"class" : "2-1"}}]}
}
后面的连续查询
当结果集为空的时候代表查询完毕
GET /_search/scroll
{"scroll":"5m","scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAC0YFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtGRZpZVI1dUEyMlNuVzBwU3JNVzR6RVlBAAAAAAAALRsWaWVSNXVBMjJTblcwcFNyTVc0ekVZQQAAAAAAAC0aFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtHBZpZVI1dUEyMlNuVzBwU3JNVzR6RVlB"
}
这个index中一共有6条数据,游标查询每次查询2条



上一篇:MySql数据库(进阶篇)