Reputation: 441
I have not found how to return total data included in the resultset. Is there any way to return total data? I need to confirm that the correct JSON data is returned.
total: 40,
page: 1,
pageSize: 3,
books: [
{
_id: 1,
title: "达·芬奇密码 ",
author: "[美] 丹·布朗",
},
{
_id: 2,
title: "梦里花落知多少",
author: "郭敬明",
},
{
_id: 3,
title: "红楼梦",
author: "[清] 曹雪芹",
}
]
}
router.get('/booksquery', (req, res) => {
var page = parseInt(req.query.page) || 1;
var limit = parseInt(req.query.limit) || 3;
Book.find({})
.sort({ update_at: -1 })
.skip((page-1) * limit)
.limit(limit)
.exec((err, doc) => {
if (err) {
res.json(err)
} else {
res.json({
total: doc.total,
page: page,
pageSize: limit,
books:doc,
});
}
})
})
Upvotes: 7
Views: 20245
Reputation: 2358
In case someone wants to see this using async/await in 2020, and some random query instead of an empty object. Remember that estimatedDocumentCount
does not work using query filters, it needs to be countDocuments
by using the query on it. Please check:
const { userId, page, limit } = req.headers;
const query = {
creator: userId,
status: {
$nin: ['deleted'],
},
};
const page_ = parseInt(page, 10) || 0;
const limit_ = parseInt(limit, 10) || 12;
const books = await BookModel.find(query)
.sort({ update_at: -1 })
.skip(page_ * limit_)
.limit(limit_);
const count = await BookModel.countDocuments(query);
Upvotes: 4
Reputation: 569
count()
is deprecated(form [email protected]). estimatedDocumentCount()
is faster than using countDocuments()
for large collections because estimatedDocumentCount()
uses collection metadata rather than scanning the entire collection.
Reference: https://mongoosejs.com/docs/api/model.html#model_Model.estimatedDocumentCount
So the code is perfect just replace countDocuments to estimatedDocumentCount
router.get("/booksquery", (req, res) => {
var page = parseInt(req.query.page) || 0; //for next page pass 1 here
var limit = parseInt(req.query.limit) || 3;
var query = {};
Book.find(query)
.sort({ update_at: -1 })
.skip(page * limit) //Notice here
.limit(limit)
.exec((err, doc) => {
if (err) {
return res.json(err);
}
Book.estimatedDocumentCount(query).exec((count_error, count) => {
if (err) {
return res.json(count_error);
}
return res.json({
total: count,
page: page,
pageSize: doc.length,
books: doc
});
});
});
});
Upvotes: 1
Reputation: 2680
Probably you could do something like this:
Only if current page index is 0 default and pagination starts with next page, that is 1, your could do .skip(page * limit) make sure .skip() and .limit() gets Number.
router.get("/booksquery", (req, res) => {
var page = parseInt(req.query.page) || 0; //for next page pass 1 here
var limit = parseInt(req.query.limit) || 3;
var query = {};
Book.find(query)
.sort({ update_at: -1 })
.skip(page * limit) //Notice here
.limit(limit)
.exec((err, doc) => {
if (err) {
return res.json(err);
}
Book.countDocuments(query).exec((count_error, count) => {
if (err) {
return res.json(count_error);
}
return res.json({
total: count,
page: page,
pageSize: doc.length,
books: doc
});
});
});
});
from above you will get response like below:
{
books: [
{
_id: 1,
title: "达·芬奇密码 ",
author: "[美] 丹·布朗"
},
{
_id: 2,
title: "梦里花落知多少",
author: "郭敬明"
},
{
_id: 3,
title: "红楼梦",
author: "[清] 曹雪芹"
}
],
total: 3,
page: 0,
pageSize: 3
}
if you use any condition and over that you want to make query and get result and total on that basics. do it inside var query ={}
.
and the same query will be used for .count()
also.
so you can get total
count on the basics of that condition.
Upvotes: 20