Skip to content

Instantly share code, notes, and snippets.

@mostafa-hz
Last active May 27, 2023 18:57
Show Gist options
  • Save mostafa-hz/425b38bbd8e1770b86a04fdf6baf004c to your computer and use it in GitHub Desktop.
Save mostafa-hz/425b38bbd8e1770b86a04fdf6baf004c to your computer and use it in GitHub Desktop.
A function to generate keyset paginated queries for mongodb
function generatePaginationQuery(query, sort, nextKey) {
const sortField = sort == null ? null : sort[0];
function nextKeyFn(items) {
if (items.length === 0) {
return null;
}
const item = items[items.length - 1];
if (sortField == null) {
return { _id: item._id };
}
return { _id: item._id, [sortField]: item[sortField] };
}
if (nextKey == null) {
return { paginatedQuery: query, nextKeyFn };
}
let paginatedQuery = query;
if (sort == null) {
paginatedQuery._id = { $gt: nextKey._id };
return { paginatedQuery, nextKey };
}
const sortOperator = sort[1] === 1 ? "$gt" : "$lt";
const paginationQuery = [
{ [sortField]: { [sortOperator]: nextKey[sortField] } },
{
$and: [
{ [sortField]: nextKey[sortField] },
{ _id: { [sortOperator]: nextKey._id } }
]
}
];
if (paginatedQuery.$or == null) {
paginatedQuery.$or = paginationQuery;
} else {
paginatedQuery = { $and: [query, { $or: paginationQuery }] };
}
return { paginatedQuery, nextKeyFn };
}
@rares-lupascu
Copy link

hey ... i think this line has a bug:

return { query, nextKeyFn };

i do not think it works for the first page because it needs to returned a named variable called paginatedQuery while here u r returning query ... so i think this needs to be:

return { paginatedQuery: query, nextKeyFn };

@mostafa-hz
Copy link
Author

@rares-lupascu you are totally right

@r-jalali
Copy link

r-jalali commented Mar 2, 2023

Imagine you have a column with duplicated data and you want to sort it. In this case this method does not work correctly. Do you have any idea? @mostafa-hz

@vijay122
Copy link

nextKeyFn helps to advance forward. How do you save the previousKey to move backward.

@mostafa-hz
Copy link
Author

@r-jalali this is where you should use a tie-breaker.
read the article here: https://medium.com/swlh/mongodb-pagination-fast-consistent-ece2a97070f3

@vijay122
Copy link

That works 👏🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment