现有一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();
})
})
}