當資料庫中資料較多,查詢的資料量較大時,很容易給mongo資料庫帶來負擔,為此,寫了一個簡單的分頁查詢算法,基于nodejs 的mongoose 子產品:
注:依賴庫:async
var findEach = function (model, condition, sort, key, views, cb) {
//model.find(condition, views).sort(sort).lean().exec(function (err, docs) {
// cb(err, docs);
//});
var allCount = 0;
var searchInterval = 2000;
var returnData = [];
async.auto({
getCount: function (cb) {
model.count(condition).lean().exec(function (err, count) {
if (!err && count) {
allCount = count;
}
cb(err);
})
},
processData: ["getCount", function (cb) {
if (allCount) {
if (allCount >= searchInterval) {
var arrLen = Math.floor(allCount / searchInterval);
var lastSearchCount = allCount % searchInterval;
var _tempArr = _.range(arrLen);
var searchIndex = 1;
var lastDataKey = null;
if (arrLen >= 1 && _tempArr.length) {
async.eachSeries(_tempArr, function (item, callback) {
if (searchIndex == 1) {
model.find(condition, views).limit(searchInterval).sort(sort).lean().exec(function (err, docs) {
if (!err && docs.length) {
lastDataKey = parseInt((docs[docs.length - 1])[key]);
searchIndex++;
returnData = returnData.concat(docs);
callback(err);
} else {
callback(err);
}
})
} else {
condition[key]["$gte"] = lastDataKey;
//console.log("condition",condition);
model.find(condition, views).limit(searchInterval).sort(sort).lean().exec(function (err, docs) {
if (!err && docs.length) {
lastDataKey = parseInt((docs[docs.length - 1])[key]);
searchIndex++;
returnData = returnData.concat(docs);
callback(err);
} else {
callback(err);
}
})
}
}, function (err, resp) {
if (!err) {
condition[key]["$gte"] = lastDataKey;
model.find(condition, views).limit(lastSearchCount).sort(sort).lean().exec(function (err, docs) {
if (!err && docs.length) {
returnData = returnData.concat(docs);
}
cb(err);
})
} else {
cb(err);
}
})
} else {
cb(null);
}
} else {
model.find(condition, views).sort(sort).lean().exec(function (err, docs) {
if (!err && docs.length) {
returnData = docs;
}
cb(err);
})
}
} else {
cb(null);
}
}]
}, function (err, resp) {
cb(err, returnData);
});
}
例子:
var Mongoose = require('mongoose');
var Schema = Mongoose.Schema;
var async= require('async');
var AdminTable = {
username: {type: String, default: ''},
password: {type: String, default: ''},
log_time: {type: Number, default: Date.now}
};
var SchemaOption = {};
var AdminSchema = new Mongoose.Schema(AdminTable, SchemaOption);
AdminSchema.statics.findAll= function (condition,views, cb) {
findEach(this, condition, {"log_time": 1}, "log_time", views, function (error, docs) {
cb(error,docs);
}
}