我有一个包含许多对象的json数据。我想限制分页数据,我需要总项数。请帮忙。
Model.find().skip((pageNumber-1)*limit).limit(limit).exec()
我想要计数并跳过数据作为回应。
答案 0 :(得分:12)
您可以使用异步库一次运行2个查询。在您的情况下,您可以运行一个查询来获取文档数量,另一个查询用于分页。
'用户'的示例模型:
var async = require('async');
var User = require('./models/user');
var countQuery = function(callback){
User.count({}, function(err, count){
if(err){ callback(err, null) }
else{
callback(null, count);
}
}
};
var retrieveQuery = function(callback){
User.find({}).skip((page-1)*PAGE_LIMIT)
.limit(PAGE_LIMIT)
.exec(function(err, doc){
if(err){ callback(err, null) }
else{
callback(null, doc);
}
}
};
async.parallel([countQuery, retrieveQuery], function(err, results){
//err contains the array of error of all the functions
//results contains an array of all the results
//results[0] will contain value of doc.length from countQuery function
//results[1] will contain doc of retrieveQuery function
//You can send the results as
res.json({users: results[1], pageLimit: PAGE_LIMIT, page: page, totalCount: results[0]});
});
async允许您并行运行多个查询,具体取决于您使用的硬件。这比使用2个独立查询来获取计数并获取所需文档更快。 希望这会有所帮助。
答案 1 :(得分:3)
您需要执行2次查询才能实现这一目标。一个用于获得结果,另一个用于获得.count()的总项目金额。
例如,您可以在" paginator"上观看的代码对于猫鼬mongoose-paginate。
答案 2 :(得分:2)
这些解决方案的问题在于,对于每个请求,您正在进行两次查询。当您拥有复杂的数据结构和大型数据集时,这会成为一个问题。请考虑创建一个特殊的函数来侦听/resource?count=true
或/resource/count
GET方法并仅返回计数。
答案 3 :(得分:2)
在猫鼬v3 +中,我已经通过$facet
和aggregate
解决了以下问题:
const [{ paginatedResult, [{ totalCount }] }] = await Model.aggregate([{
$facet: {
paginatedResult: [
{ $match: query },
{ $skip: skip },
{ $limit: limit }
],
totalCount: [
{ $match: query },
{ $count: 'totalCount' }
]
}
}])
其中totalCount
是指与搜索查询匹配的记录总数,而paginatedResult
只是它们的分页片段。
答案 4 :(得分:-1)
要仅执行一个查询,您可以使用与promises和数组切片关联的find()方法。一个小例子是:
getPaginated(query, skip, limit){
return this.model.find(query)
.lean()
.then((value)=>{
if (value.length === 0) return {userMessage: 'Document not found'};
const count = value.length;
//skip===0 must be handled
const start = parseInt(limit)*parseInt(skip - 1);
const end = start + parseInt(reqQuery.pagesize);
//slicing the array
value = value.slice(start,end);
//could return it another way...
value.push( { 'querySize': count });
return value;
})
.catch((reason)=>{
//...handling code
});
}