無論是傳統網頁還是 ajax api,我們都不得不進行數據分頁,一來節省帶寬二來提升頁面響應速度。作為一個數據完備的 web 應用,做好分頁功能能極大提升用戶體驗。
簡單的分頁查詢
在 mongoose 中,我們可以利用 skip、limit來進行分頁:
Articl.find({})
.skip(page * 5)
.limit(5)
.sort({'_id':-1})
.exec(cb);
根據前端傳入的 page 來跳過相應的頁數,在進行查詢返回結果。
分頁查詢優化
上面的方法在數據量較小的情況下運行的很好,但一旦數據較大很容易出現性能瓶頸。有沒有更好的方式呢?
find + limit
我們知道,保存在 mongodb 數據庫中對象有一個唯一的id:ObjectId,借此,我們可以利用它搞一些事情。
還記得 $gt、$lt 嗎?我們要求前端返回一個 ObjectId ,通過 .find({'_id': {"$lt": ObjectId}}) 來實現查找,具體如下:
ArticleSchema.statics = {
fetch(id, cb) {
if (id) {
return this.find({'_id': {"$lt": id}})
.limit(5)
.sort({'_id':-1})
.exec(cb);
}else {
return this.find({})
.limit(5)
.sort({'_id':-1})
.exec(cb);
}
}
}
這樣,我們就能獲取到在給定 id 后面的數據了。
避免用戶無效點擊
有了分頁就需要用戶點擊查詢,這里引申出另一個問題————如何避免無效點擊?這里的無效指用戶點擊下一頁后返回空數據。
方案一:比較返回數據長度
通過比較返回數據的實際長度和每頁最大數據長度的值,如果實際長度 < 最大長度,說明下頁為空了。潛在的問題是,如果他們相等,但下頁數據為空,也會造成一次無效點擊。
方案二:獲取數據總長度
通過獲取數據的總長度,除以頁面顯示的頁數,得到總頁數,這樣就能完全避免上述問題。
在 mongoose 中,可以通過 .count() 方法獲取模型數據的總長度:
Article.count({}, (err, count) => {
Article.fetch(id, (err, data) => { // 上面定義的方法 fetch
if(err) next(err);
res.render('articleList.art', { title: '文章列表', articles: data, count } );
})
})