1.问题产生:当从es中查出跨度为好几个月的日志时,直接点击第三千多页时出现错误查不出数据。
2.问题产生原因分析:首先用户查询跨度好几个月的日志然后直接点击第三千多页,也就是说用户要查第三万多条的日志记录。这一操作就会导致es返回不了相应的数据。因为elasticsearch是分布式搜索引擎,索引的数据拆分存储在各个分片中的,每个分片可能会散布在es集群的各个节点上。这样的话分页查询就不同于传统的数据库,就拿用户的操作来说,他要查第三千页的数据(每页十条),平均每个月的日志索引会有将近三十万条日志数据,那么就是在每个索引中取出30010条然后汇总再进行排序取最后的十条。当索引中分片数越多的时候,需要汇总的数据会成倍增长,这种直接查几千页的查询操作可能会拖垮es集群。
3.解决方案:由于查跨度几个月的日志然后点击第几千页的操作就是不合适的,那么可以直接把分页做成类似百度的那种分页。然后发现在百度进行数据检索的时候可能会查出百万条数据,但是百度也没有给我们提供直接跳转到几千页的这种不合理的操作,而是让用户一页一页的跳转,如下:
那么就仿照把分页改成这种样式
<template> <div class="paging-all"> <div class="page-size">共{{totalPage}}页</div> <ul> <li @click="pageChange(currentPage - 1)"><上一页</li> <li :class="currentPage === item.val ? 'active' : ''" v-for="item in pageList" v-text="item.text" @click="pageChange(item.val)"></li> <li @click="pageChange(currentPage + 1)">>下一页</li> </ul> </div> </template> <script> export default { name: 'Paging', props: { pageSize: { type: Number, default: 10 }, total: { type: Number, default: 0 }, currentPage: { type: Number, default: 1 } }, data () { return { pageGroup: 10 // 可见分页量,默认为十页 } }, computed: { totalPage () { return Math.ceil(this.total / this.pageSize) }, pageList () { var list = [] var count = Math.floor(this.pageGroup / 2) var left = 1 var right = this.totalPage var center = this.currentPage if (this.totalPage > this.pageGroup) { if (center > count + 1) { if (center + count > right) { left = right - this.pageGroup + 1 } else { left = center - count right = center + count - 1 } } else { right = this.pageGroup } } while (left <= right) { list.push({ text: left, val: left }) left++ } return list } }, methods: { pageChange (curpage) { if (curpage > 0 && curpage <= this.totalPage && curpage !== this.currentPage) { this.$emit('change', {curPage: Number(curpage)}) } } } } </script> <style lang="stylus" scoped> .paging-all { margin: 0 auto; overflow: hidden; text-align: center; display: inline-block; } .page-size { height: 26px; line-height: 26px; display: inline-block; } ul { list-style: none; display: inline-block; } ul li { display: inline-block; padding: 2px 8px; cursor: pointer; border-radius: 2px; margin: 0 5px; color: #606266; border: 1px solid #A0B1BB background: #FFFFFF; &:hover { background #f2f8ff border: 1px solid #38f } &.active { background #f2f8ff border: none color: #38f } } </style>