I’m working on a pagination implementation using MongoDB’s aggregation pipeline. Specifically, I want to paginate articles by fetching only documents with _id values less than a given after value (for “load more” behavior). I implemented this using $match with a filter like { _id: { $lt: new ObjectId(after) } }, and it works fine with find() but returns an empty array when applied inside an aggregation pipeline.
Here’s my current pipeline:
const query = after ? { _id: { $lt: new mongoose.Types.ObjectId(after) } } : {};
articleModel.aggregate([
{ $match: query },
{ $sort: { createdAt: -1 } },
{ $limit: 10 },
{
$lookup: {
from: 'users',
localField: 'owner',
foreignField: '_id',
as: 'doctorInfo'
}
},
{ $unwind: { path: '$doctorInfo', preserveNullAndEmptyArrays: true } }
]);
This setup results in an empty response, even though there are documents with _id values less than the specified after value. I’m not sure why this is happening since the same logic works perfectly with find() queries.
I initially thought the issue might be with how I’m constructing the $match query, so I hardcoded it like this:
{ _id: { $lt: new mongoose.Types.ObjectId('64f1b28bfaf999c9a7bf3d21') } }
Still, I got an empty array even though documents with _id values less than that one exist in the collection.
I checked if the issue was related to the order of stages in my aggregation pipeline. I also tried moving the $match stage to different positions in the pipeline, but the result remained the same.
I expected the aggregation query to return documents like how it works with find(), but it seems the pipeline doesn’t respect the _id filtering when used with aggregation.
I found this discussion suggesting facet-based pagination, but I’m not sure if that’s the best approach or how exactly to implement it for my use case.