mongodb页面展示列表时遇到展示慢的问题

当我们开发程序的时候逃不开的就是写增删改查,当进行增删改操作的时候很多会遇到并发的问题,而当查询的时候如果数据量过大,那么查询就会很慢,查询很少的数据可能就会几秒甚至几十秒的时间,而很多人选择的方式就是加索引,同样的我们很多开发人员用到了mongodb存储类似日志之类的大数据,然后mongodb由于业务的增多和时间的积累,可能数量到达一定程度之后,查询也会变的很慢,加了索引之后也是如此,在通过调试之后发现了一个问题。

当我们查询的时候很多情况下最耗费时间的其实是count方法,很多人也换成了size方法,但是速度还是相差不远,所以能做的就是在分页展示的时候尽量少的去查询总数,不查询总数同样也是可以实现分页操作的,从而大大简化搜索时间。

基本思路是,页面的上一页和下一页把展示过的条数和要显示的条数都传过去,传到后台mongodb里面作为参数

DBCursor limit =this.getCollection().find(condition).skip(query.getPageIndex()).sort(basicDBObject).limit(query.getPageSize());

而点击下一页的时候是否到最后可以通过分页显示的条数和这个展示的条数来判断,同理,第一页的展示条数永远是0开始,比较特殊的情况是当最后一页的条数恰巧等于展示数量,那么直接展示最后一页或者暂无数据都是可以的,实现的代码展示如下:

1.分页工具

package com.group.erp.common.util;
import java.util.ArrayList;
public  class PaginatedMongoArrayList<T> extends ArrayList<T> implements PaginatedMongoList<T>{
    private static final long serialVersionUID = 2841788433467303352L;
    public static final int PAGESIZE_DEFAULT = 20;
    private int pageSize;
    private int startRows;
    private int countItem;
    public PaginatedMongoArrayList() {
        //repaginate();
    }
    public PaginatedMongoArrayList(int startRows, int pageSize) {
        this.startRows = startRows;
        this.pageSize = pageSize;
        //repaginate();
    }
    public boolean isFirstPage() {
        return this.startRows <= 0;
    }
    public int getCountItem() {
        return countItem;
    }
    public void setCountItem(int countItem) {
        this.countItem = countItem;
    }
    public boolean isLastPage() {
        return this.pageSize > this.countItem;
    }
    public boolean isNextPageAvailable() {
        return !isLastPage();
    }
    public boolean isPreviousPageAvailable() {
        return !isFirstPage();
    }
    public int getNextPage() {
        if (isLastPage()) {
            return this.startRows;
        }
        return this.startRows + this.pageSize;
    }
    @Override
    public int getPreviousPage() {
        if (isFirstPage()) {
            return 0;
        }
        return this.startRows - this.pageSize;
    }
    public int getPageSize() {
        return this.pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
        //repaginate();
    }
    @Override
    public boolean isMiddlePage() {
        // TODO Auto-generated method stub
        return false;
    }
    @Override
    public int getIndex() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public void setIndex(int paramInt) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public int getTotalItem() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public void setTotalItem(int paramInt) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public int getTotalPage() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public int getStartRow() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public int getEndRow() {
        // TODO Auto-generated method stub
        return 0;
    }
    
}
package com.group.erp.common.util;

import java.util.List;

public  interface PaginatedMongoList<T> extends List<T> {
    /**
     * @描述 : 是否是中间页
     * 
     * @return
     */
    public  boolean isMiddlePage();

    /**
     * @描述 : 是否是末页
     * 
     * @return
     */
    public  boolean isLastPage();

    /**
     * @描述 : 下一页是否可用
     * 
     * @return
     */
    public  boolean isNextPageAvailable();

    /**
     * @描述 : 上一页是否可用
     * 
     * @return
     */
    public  boolean isPreviousPageAvailable();

    /**
     * @描述 : 获取总页数
     * 
     * @return
     */
    public  int getPageSize();

    public  void setPageSize(int paramInt);

    /**
     * @描述 : 获取当前页
     * 
     * @return
     */
    public  int getIndex();

    public  void setIndex(int paramInt);

    /**
     * @描述 : 获取数据总条数
     * 
     * @return
     */
    public  int getTotalItem();

    public  void setTotalItem(int paramInt);

    /**
     * @描述 : 获取总页数
     * 
     * @return
     */
    public  int getTotalPage();

    /**
     * @描述 : 起始条数
     * 
     * @return
     */
    public  int getStartRow();

    /**
     * @描述 : 结束条数
     * 
     * @return
     */
    public  int getEndRow();

    /**
     * @描述 : 下一页
     * 
     * @return
     */
    public  int getNextPage();

    /**
     * @描述 : 上一页
     * 
     * @return
     */
    public  int getPreviousPage();

    /**
     * @描述 : 是否是第一页
     * 
     * @return
     */
    public  boolean isFirstPage();
}

velocity的分页宏:

#macro (showPage $module $page)
    #if($page)
        <div class="span12"><div class="dataTables_info" id="DataTables_Table_0_info">共有 $!page.totalItem 条记录 $!page.index/$!{page.totalPage}页</div></div>
        <div class="span12 center">
        <div class="dataTables_paginate paging_bootstrap pagination">
        <ul>
             <li class="disabled"><a href="javascript:void(0);">每页显示</a></li>
             <li class="s-page">
                <select id="selSize" style="width:auto;height:33px;display:block;float:left;" onchange="goToSize(‘$module.addQueryData("kw","").render()‘,‘1‘,this.value)">
                    #foreach($i in [10,20,30,40,50])
                        #if($!{page.pageSize}==$i)
                            <option value="$!i" selected="selected">$!i</option>
                        #else
                            <option value="$!i" >$!i</option>
                        #end
                    #end
                </select>
             </li>
             <li class="disabled"><a href="javascript:void(0);">行</a></li>
        #set($pagePos = 2) ##当前页的尾巴长度
        #if($page.previousPageAvailable) ##如果能向上翻页
        <li><a href="javascript:goToSize(‘$module.render()‘,‘$!{page.previousPage}‘,$!{page.pageSize})">上一页<b></b></a></li>
        <li><a href="javascript:goToSize(‘$module.render()‘,‘1‘,$!{page.pageSize})">首页</a></li>
        #else
           <li class="disabled"><a href="#">上一页<b></b></a></li>
           <li class="disabled"><a href="#">首页</a></li>
        #end
        #foreach($i in [$pagePos..1]) ##增加前面的尾巴
        #if($!page.index - $i > 0)
            #set($pageIndex= $!page.index - $i)
            <li><a href="javascript:goToSize(‘$module.render()‘,$!{pageIndex},$!{page.pageSize})">$pageIndex</a></li>
        #end
        #end
        <li class="active"><a>$!page.index</a></li>
        ##显示当前页号
        #foreach($i in [1..$pagePos]) ##增加后面的尾巴
        #if($!page.totalPage - $!page.index - $i >= 0)
            #set($pageIndex= $!page.index + $!i)
           <li><a href="javascript:goToSize(‘$module.render()‘,$!{pageIndex},$!{page.pageSize})">$pageIndex</a></li>
        #end
        #end
        #if($page.nextPageAvailable) ##显示后面的页
        <li><a href="javascript:goToSize(‘$module.render()‘,‘$!{page.totalPage}‘,‘$!{page.pageSize}‘)">末页</a></li>
        <li><a href="javascript:goToSize(‘$module.render()‘,‘$!{page.nextPage}‘,$!{page.pageSize})">下一页<b></b></a></li>
        #else
            <li class="disabled"><a href="#">末页</a></li>
            <li class="disabled"><a href="#">下一页<b></b></a></li>
        #end
         <li class="s-page">跳转到</li>
         <li class="s-page">
            <select id="selPage" style="width:auto;height:33px;display:block;float:left;" onchange="goToPage(‘$module.render()‘,this.value,$!{page.pageSize})">
            #foreach($i in [1..$!page.totalPage])
                #if($!page.index == $!i)
                <option value="$!i" selected ="selected">$!i</option>
                #else
                <option value="$!i">$!i</option>
                #end
            #end
            </select>
         </li>
        </ul>
        </div>
        </div>
        $!module.reset() 
    #end
#end
#macro (showAjaxPage $module $page)
    #if($page)
        <div class="pull-left"><div class="dataTables_info" id="datatable2_info">共有 $!page.totalItem 条记录 $!page.index/$!{page.totalPage}页</div></div>    
        
        <div class="pull-right">
        <div class="dataTables_paginate paging_bs_full">
        <ul class="pagination">
             <li class="disabled"><a href="javascript:void(0);">每页显示</a></li>
             <li >
                <select id="selSize" style="width:auto;height:33px;display:block;float:left;" onchange="goSize(‘$module.addQueryData("kw","").render()‘,‘1‘,this.value)">
                    #foreach($i in [10,20,30,40,50])
                        #if($!{page.pageSize}==$i)
                            <option value="$!i" selected="selected">$!i</option>
                        #else
                            <option value="$!i" >$!i</option>
                        #end
                    #end
                </select>
                
             </li>
             <li class="disabled"><a href="javascript:void(0);">行</a></li>
        #set($pagePos = 2) ##当前页的尾巴长度
        #if($page.previousPageAvailable) ##如果能向上翻页
        <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,‘$!{page.previousPage}‘,$!{page.pageSize})">上一页<b></b></a></li>
        <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,‘1‘,$!{page.pageSize})">首页</a></li>
        #else
           <li class="disabled"><a href="javascript:void(0);">上一页<b></b></a></li>
           <li class="disabled"><a href="javascript:void(0);">首页</a></li>
        #end
        #foreach($i in [$pagePos..1]) ##增加前面的尾巴
        #if($!page.index - $i > 0)
            #set($pageIndex= $!page.index - $i)
            <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,$!{pageIndex},$!{page.pageSize})">$pageIndex</a></li>
        #end
        #end
        <li class="active"><a >$!page.index</a></li>
        ##显示当前页号
        #foreach($i in [1..$pagePos]) ##增加后面的尾巴
        #if($!page.totalPage - $!page.index - $i >= 0)
            #set($pageIndex= $!page.index + $!i)
           <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,$!{pageIndex},$!{page.pageSize})">$pageIndex</a></li>
        #end
        #end
        #if($page.nextPageAvailable) ##显示后面的页
        <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,‘$!{page.totalPage}‘,‘$!{page.pageSize}‘)">末页</a></li>
        <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,‘$!{page.nextPage}‘,$!{page.pageSize})">下一页<b></b></a></li>
        #else
            <li class="disabled"><a href="javascript:void(0);">末页</a></li>
            <li class="disabled"><a href="javascript:void(0);">下一页<b></b></a></li>
        #end
         <li class="disabled"><a href="javascript:void(0);">跳转到</a></li>
         <li >
            <input id="selPage" type="text" style="width:34px;height:33px;"  value="$!{page.index}" onblur="goPage(‘$module.render()‘,this.value,$!{page.pageSize},$!page.totalPage)"/>页
         </li>
        </ul>
        </div>
        </div>
        </div>
        $!module.reset() 
    #end
#end
#macro (showAjaxMongoPage $module $page)
    #if($page)
        <div class="pull-right">
        <div class="dataTables_paginate paging_bs_full">
        <ul class="pagination">
             <li class="disabled"><a href="javascript:void(0);">每页显示</a></li>
             <li >
                <select id="selSize" style="width:auto;height:33px;display:block;float:left;" onchange="goSize(‘$module.addQueryData("kw","").render()‘,‘0‘,this.value)">
                    #foreach($i in [10,20,30,40,50])
                        #if($!{page.pageSize}==$i)
                            <option value="$!i" selected="selected">$!i</option>
                        #else
                            <option value="$!i" >$!i</option>
                        #end
                    #end
                </select>
                
             </li>
             <li class="disabled"><a href="javascript:void(0);">行</a></li>
        #set($pagePos = 2) ##当前页的尾巴长度
        #if($page.previousPageAvailable) ##如果能向上翻页
        <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,‘$!{page.previousPage}‘,$!{page.pageSize})">上一页<b></b></a></li>
        #else
           <li class="disabled"><a href="javascript:void(0);">上一页<b></b></a></li>
        #end
        #if($page.nextPageAvailable) ##显示后面的页
        <li><a href="javascript:void(0);" onclick="goSize(‘$module.render()‘,‘$!{page.nextPage}‘,$!{page.pageSize})">下一页<b></b></a></li>
        #else
            <li class="disabled"><a href="javascript:void(0);">下一页<b></b></a></li>
        #end
        </ul>
        </div>
        </div>
        </div>
        $!module.reset() 
    #end
#end

service层:

@Override
    public Result getCoreLogList(CoreLogQuery query) {
        Result result=new Result();
        // int count=    coreLogManager.queryCoreLogCount(query);
        // if(count>0){
        PaginatedMongoArrayList<CoreLog> pageList = new PaginatedMongoArrayList<CoreLog>(
                        query.getPageIndex(), query.getPageSize());
                
        List<CoreLog> coreLogList= coreLogManager.queryCoreLog(query);
        
                pageList.setCountItem(coreLogList.size());
                query.setStartRow(query.getPageIndex());
                pageList.addAll(coreLogList);
                result.addModel("pageList", pageList);
                result.addModel("msg", "success");
        // }
        return result;
    }

欢迎提出宝贵意见

时间: 2024-10-12 19:52:27

mongodb页面展示列表时遇到展示慢的问题的相关文章

salesforce lightning零基础学习(七) 列表展示数据时两种自定义编辑页面

上一篇Lightning内容描述的是LDS,通过LDS可以很方便的实例化一个对象的数据信息.当我们通过列表展示数据需要编辑时,我们常使用两种方式去处理编辑页面:Pop Up Window弹出修改详情以及在本页面隐藏详情页面显示编辑页面. 实现这个功能以前主要需要先了解几个标签: lightning:recordForm: 此标签允许用户快速的创建一个form去查看,添加以及修改一条记录.集合了 lightning:recordEditForm 以及 lightning:recordViewFor

【黑马Android】(04)数据库的创建和sql语句增删改查/LinearLayout展示列表数据/ListView的使用和BaseAdater/内容提供者创建

数据库的创建和sql语句增删改查 1. 加载驱动. 2. 连接数据库. 3. 操作数据库. 创建表: create table person( _id integer primary key, name varchar(20), age integer ); 添加: insert into person(name, age) values('lisi', 19); 删除: delete from person where _id = 1; 修改: update person set name =

以+scheduledTimerWithTimeInterval...的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?

这里强调一点:在主线程中以+scheduledTimerWithTimeInterval...的方式触发的timer默认是运行在NSDefaultRunLoopMode模式下的,当滑动页面上的列表时,进入了UITrackingRunLoopMode模式,这时候timer就会停止 可以修改timer的运行模式为NSRunLoopCommonModes,这样定时器就可以一直运行了 以下是我的笔记补充: 在子线程中通过scheduledTimerWithTimeInterval:...方法来构建NST

JSFF或JSF页面加载时触发JavaScript之方法

现象一 最近在项目中遇到这么一个问题,有些页面元素是在页面加载时通过JavaScript动态渲染而成.当生成这些元素的JavaScript脚本被放置于JSPX文件中时,界面渲染没有问题.但是当我们把生成这些页面元素的JS脚本放到JSFF时就会发现,JS脚本只在我们进入TaskFlow的第一个View被执行了,进入后续View时,后续View的JS代码加载和执行. 分析 通过分析,发现当进入TaskFlow的第一个View时,第一个View中通过<af:resource/>标签引入的JS代码能成

如何自动在html页面加载时动态改变div等元素的高度和宽度

这里需要用到jquery + css.原理是在页面加载时用javascript去动态改变一个class的高度和宽度.这样结合javascript能动态获取浏览器/页面的高度和宽度,从而使得div能动态的跟随浏览页面的大小变化而变化并且不影响高宽比.下面的代码创建一个手机页面,每一行三个图片分占33%,每个图片div的高和宽会随着浏览器的大小变化而自适应. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"

Javascript在页面加载时的执行顺序【转】

一.在HTML中嵌入Javasript的方法 直接在Javascript代码放在标记对<script>和</script>之间 由<script />标记的src属性制定外部的js文件 放在事件处理程序中,比如:<p onclick="alert('我是由onclick事件执行的Javascript')">点击我</p> 作为URL的主体,这个URL使用特殊的Javascript:协议,比如:<a href="

页面加载时让其显示笼罩层与加载等待图片

页面加载时让其显示笼罩层与加载等待图片(结局比较完美,过程很坎坷,所以一定总结整理下,备用): 用了ajax异步,是因为js内容不能即时的显示出来,因为js是单线程,要把队列中的任务执行完后才会执行刚才对js的处理 要用beforeSend,complete的时候必须要用ajax异步 beforeSend: function () {},//程序一开始便会执行该函数,使用该方法必须使用异步ajax complete: function () {},//complete在success或error

页面加载时的 Loading 效果

//页面加载时的 Loading 效果 $(window).load(function () { window.setTimeout(function () { $('body').removeClass('loading'); }, 1000); }); 上面的JS部分: HTML 部分 <body class="loading"> <div class="main"> </div></body> css .load

js 判断 当页面无法回退时(history.go(-1)),关闭网页

在做一个Web项目时遇到一个需求,当页面没有前驱历史记录时(就是当前为新弹出的页面,没法做goback操作即history.go(-1)),点击返回按钮时直接关闭页面,否则就退回到前一页. 遇到的问题就是如何判断 是否有history可以回退,这个非常麻烦,因为没有这样的函数直接能获取到,只能通过history.length这个变量做变通的处理,但是对于IE,和非IE的length的返回值不同,ie: history.length=0, 非IE的为1,因此写了一个函数实现前面所需求的这个功能.分