分页正确做法的分析

现有一data数据库,data里面student集合中信息如下:
这里写图片描述

集合中的文档信息很多,现我们希望通过用户向浏览器输入的url的page参数(即第几页)来想数据库中读取信息,每次读取10条信息
那现在我们有两种做法:
1)将所有的result都读取到数组中去,然后进行数据分页的操作
代码实现如下:

var express = require("express");
var app = express();
var db = require("./model/db.js");
app.get("/",function (req,res) {
    //url就是数据库的地址/表示数据库
    //假如数据库不存在,没关系,程序会自动帮我们创建一个数据库
    db.insertOne("student",{"name":"小胡","age":20},function (err,result) {
        if(err){
            console.log("插入数据失败");
            return;
        }
        console.log("插入数据成功");
        res.send("插入数据成功");
    })
})
app.get("/find",function (req,res) {
    //这个页面现在接受一个page 参数
    //注意:这里面的Page是一个字符串,应该将它转化为数字,因为否则后面的就是字符串拼接
    var page = parseInt(req.query.page); //express椎间盘没喝过读取get参数很简单

    //调用find这个方法会自动连接数据库,内部调用了连接数据库的方法
    db.find("student",{},function (err,result) {
    //我们将数据库中student集合中所有的信息全部存储到result数组中去,然后根据page来从result中拿到对应数据
        if(err){
            console.log("数据查找失败");
            return;
        }
        var a = [];
        db.find("student",{},function (err,result) {
            var totalpage = Math.ceil(result.length/10);
             //判断用户所请求的页数有没有超过总共的页数
            if(page >= totalpage){
                page = totalpage-1;
                for(var i = 10*page;i< result.length; i++) {
                    //注意不能在这个地方将result[i]逐条发送出去,因为响应只能发送一次
                    a.push(result[i]);
                }
                res.send(a);
                return;
            }
            for(var i = 10*page;i< 10*(page+1); i++) {
                //注意不能在这个地方将result[i]逐条发送出去,因为响应只能发送一次
                a.push(result[i]);
            }


            res.send(a);
        });

        // res.writeHeader(200, {'Content-Type':'text/html;charset=UTF-8'})

    })
})
app.listen(3000);

上面的做法显然不是最优化的,假想一盒用户只需要请求第三页的信息,然而我们这种做法确实将集合中所有的信息全部加载到数组中去,这样开销很大,这样显然不是最优化的方法。
在mongodb中提供了limit和skip的方法:
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
我们将连接数据库以及数据库的增删改查的方法封装为一个模块,向外暴露接口,提供函数

/这个模块里面封装了对所有数据库的常用操作
//不管数据库的什么操作,都要先连接数据库,所以我们可以把连接数据库封装为一个函数
var MongoClient = require("mongodb");
var setting = require("../setting")
//我们直接将数据库连接的函数封装起来,每次调用相关的函数,不用关系低层的代码
//连接数据库
function __connectDB(callback) {
    //从setting文件中读取地址
    var url = setting.dburl;
    //连接数据库
    MongoClient.connect(url,function (err,db) {
        if(err){
            console.log(err);
            console.log("连接失败");
            return;
        }
        console.log("连接成功了");
        //当数据库连接成功之后调用回调函数做的事情
        console.log(db);
        callback(err,db);

    })
}
//插入数据
exports.insertMany = function (collectionName,array,callback) {
    __connectDB(function (err,db) {
        if(err){
            callback(err,db);
            db.close();
            return;
        }
        db.collection(collectionName).insertMany(array,function (err,result) {
          callback(err,result);
          db.close();
        })


    })
}
//查找数据,找到所有的数据
//用户可以不传args参数
//由于JS函数没有重载的概念,也就是后面同名但是参数个数不同的函数会覆盖前面的函数
exports.find = function (collectionName,json,C,D) {
    var result = []; //结果将数组输出,不用多次调用回调函数
  if(arguments.length == 3){
      //当函数的参数为3时
      //传进来的第三个参数即函数我们将其命名为回调函数
      var callback = C;
      //当不传入参数进入数组时,那么久默认取到集合中所有的数据
      var skipnumber = 0;
      var limit = 0;
  }else if(arguments.length == 4){
      var callback = D;
      var args = C;
      //应该省略的条数
      var skipnumber = args.pageamout*args.page;
      var limit = args.pageamout;
  }else{
      throw new Error("find函数的参数个数是三个或者四个");
  }
  // //表示我们要跳过的的个数
  //   var skipnumber = args.pageamout*args.page;
  // //表示我们需要查找的页数
  //   var limit = args.pageamout;
    console.log(skipnumber);
    console.log(limit);
    __connectDB(function (err,db) {
        //当与数据库建立连接之后,开始查询数据
        //使用游标遍历一个个文档
        console.log(db);

        var cursor = db.collection(collectionName).find(json).skip(skipnumber).limit(limit);
        cursor.each(function (err,doc) {
             if(doc != null){
                 result.push(doc);
             }else{
                 //遍历文档结束,没有更多的文档了
                 //给find方法里面传入回调函数,并将的到的文档数组传入回调函数中去
                 callback(null,result);
                 db.close();
             }
        })
    })
}
//向外暴露删除
exports.deleteMany = function (collectionName,json,callback) {
    __connectDB(function (err,db) {
        db.collection(collectionName).deleteMany(json,function (err,results) {
            //表示删除数据之后应该做的事情
                callback(err,results);
                db.close();
            })

    })
}

//修改,json1为我们要查找的那个条件,json2表示那我们要修改为的那个json问题
exports.updateMany = function (collectionName,json1,json2,callback) {
    __connectDB(function (err,db) {
        db.collection(collectionName).updateMany(json1, {$set: json2}, {$currentDate: { lastModified: true }} ,function (err,results) {
            if(err){
                console.log(err);
                console.log("修改失败");
                db.close();
                return;
            }
           callback(err,results);
            db.close();

        })

    })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值