To jest rozwiązanie, którego użyłem, gdy moja kolekcja stała się zbyt duża, aby można ją było zwrócić w pojedynczym zapytaniu. Wykorzystuje nieodłączną kolejność _id
pola i umożliwia zapętlenie kolekcji według określonego rozmiaru partii.
Tutaj jest to moduł npm, mongoose-paging , pełny kod jest poniżej:
function promiseWhile(condition, action) {
return new Promise(function(resolve, reject) {
process.nextTick(function loop() {
if(!condition()) {
resolve();
} else {
action().then(loop).catch(reject);
}
});
});
}
function findPaged(query, fields, options, iterator, cb) {
var Model = this,
step = options.step,
cursor = null,
length = null;
promiseWhile(function() {
return ( length===null || length > 0 );
}, function() {
return new Promise(function(resolve, reject) {
if(cursor) query['_id'] = { $gt: cursor };
Model.find(query, fields, options).sort({_id: 1}).limit(step).exec(function(err, items) {
if(err) {
reject(err);
} else {
length = items.length;
if(length > 0) {
cursor = items[length - 1]._id;
iterator(items, function(err) {
if(err) {
reject(err);
} else {
resolve();
}
});
} else {
resolve();
}
}
});
});
}).then(cb).catch(cb);
}
module.exports = function(schema) {
schema.statics.findPaged = findPaged;
};
Dołącz go do swojego modelu w następujący sposób:
MySchema.plugin(findPaged);
Następnie zapytaj w ten sposób:
MyModel.findPaged(
{source: 'email'},
['subject', 'message'],
{step: 100},
function(results, cb) {
console.log(results);
cb();
cb(err);
},
function(err) {
throw err;
}
);