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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
    }


欢迎提出宝贵意见

本文出自 “精忠报国” 博客,请务必保留此出处http://xinsir.blog.51cto.com/5038915/1861950

以上是关于mongodb页面展示列表时遇到展示慢的问题的主要内容,如果未能解决你的问题,请参考以下文章

nodejs + mongodb + ejs + express 实现页面展示 connection

小程序列表页开发

海外web平台访问速度慢的原因之一

[Nowcoder] 列表补全

完成前台门户页面系统功能门户页面商品列表展示的功能

WordPress无法新发布文章和页面,提示您正在编辑展示最新文章的页面