Có một giải pháp sử dụng push và lát: https://stackoverflow.com/a/39784851/4752635
tôi prefe
- Đầu tiên để lọc và sau đó nhóm theo ID để nhận số lượng phần tử được lọc. Không lọc ở đây, nó là không cần thiết.
- Truy vấn thứ hai lọc, sắp xếp và phân loại.
Giải pháp với việc đẩy $$ ROOT và sử dụng $ slice chạy vào giới hạn bộ nhớ tài liệu 16MB cho các bộ sưu tập lớn. Ngoài ra, đối với các bộ sưu tập lớn, hai truy vấn cùng nhau dường như chạy nhanh hơn so với một bộ lọc có ROOT $ đẩy. Bạn có thể chạy chúng song song là tốt, vì vậy bạn bị giới hạn bởi chậm hơn của hai truy vấn (có thể là một trong những loại đó).
tôi đã giải quyết với giải pháp này sử dụng 2 truy vấn và khuôn khổ hợp (lưu ý - Tôi sử dụng Node.js trong ví dụ này, nhưng ý tưởng là như nhau):
var aggregation = [
{
// If you can match fields at the begining, match as many as early as possible.
$match: {...}
},
{
// Projection.
$project: {...}
},
{
// Some things you can match only after projection or grouping, so do it now.
$match: {...}
}
];
// Copy filtering elements from the pipeline - this is the same for both counting number of fileter elements and for pagination queries.
var aggregationPaginated = aggregation.slice(0);
// Count filtered elements.
aggregation.push(
{
$group: {
_id: null,
count: { $sum: 1 }
}
}
);
// Sort in pagination query.
aggregationPaginated.push(
{
$sort: sorting
}
);
// Paginate.
aggregationPaginated.push(
{
$limit: skip + length
},
{
$skip: skip
}
);
// I use mongoose.
// Get total count.
model.count(function(errCount, totalCount) {
// Count filtered.
model.aggregate(aggregation)
.allowDiskUse(true)
.exec(
function(errFind, documents) {
if (errFind) {
// Errors.
res.status(503);
return res.json({
'success': false,
'response': 'err_counting'
});
}
else {
// Number of filtered elements.
var numFiltered = documents[0].count;
// Filter, sort and pagiante.
model.request.aggregate(aggregationPaginated)
.allowDiskUse(true)
.exec(
function(errFindP, documentsP) {
if (errFindP) {
// Errors.
res.status(503);
return res.json({
'success': false,
'response': 'err_pagination'
});
}
else {
return res.json({
'success': true,
'recordsTotal': totalCount,
'recordsFiltered': numFiltered,
'response': documentsP
});
}
});
}
});
});
Nguồn
2017-02-09 17:46:12
Tính đến mongoengine, 'Lỗi Loại: with_limit_and_skip phải là True hoặc False', đếm (Đúng) sẽ thực hiện công việc – kkzxak47