Mongoose plugin with offset (skip/limit) and keyset (last-seen) pagination.
npm install @mongoosejs/paginationimport mongoose from 'mongoose';
import pagination from '@mongoosejs/pagination';
const postSchema = pagination(new mongoose.Schema({
authorId: mongoose.Schema.Types.ObjectId,
createdAt: Date
}));
const Post = mongoose.model('Post', postSchema);
// Supports limit/skip based pagination
const posts = await Post.paginate(
{ authorId },
{ sort: { createdAt: -1, _id: -1 }, limit: 20, skip: 20 }
);
// Also supports keyset pagination via `after` option
const morePosts = await Post.paginate(
{ authorId },
{
sort: { createdAt: -1, _id: -1 },
limit: 20,
after: {
createdAt: posts[posts.length - 1].createdAt,
_id: posts[posts.length - 1]._id
}
}
);
// Can also pass the full document as `after`
const evenMorePosts = await Post.paginate(
{ authorId },
{
sort: { createdAt: -1, _id: -1 },
limit: 20,
after: posts[posts.length - 1]
}
);sort and limit are required.
You may also pass skip (offset pagination) or after (keyset pagination), but not both.
With neither, you get the first page.
For last-seen pagination, pass the values from the final document as after.
after must contain every key in sort; additional keys are ignored, so you can pass the last document itself.
const options = { sort: { createdAt: -1, _id: -1 }, limit: 20 };
const posts = await Post.paginate({ authorId }, options);
const morePosts = await Post.paginate(
{ authorId },
{ ...options, after: posts[posts.length - 1] }
);Options other than sort, limit, skip, and after are passed to the Mongoose query.
npm test
npm run test:types