Reputation: 13
I have a collection with articles. Because the collection is very big I have to use range queries for pagination (instead of the skip method).
In order to take the first page (of the most recent articles) using a range query on _id its straight forward:
db.articles.find({}, {title:1}).limit(10).sort({_id:-1})
In order to take the next page again is straightforward:
db.articles.find({"_id":{"$lt":ObjectId("43...75")}}, {title:1}).limit(10).sort({_id:-1})
(where the ObjectId is the _id of the last article of the current page)
And here comes the question: "How do i get the PREVIOUS page???"
My first thought was to use the same query using $gt instead of $lt and the _id of the first article of the current page. This however is wrong because if the current page has articles 50-60 the previous page will be 1-10.
In order to overcome this shortcoming, i could sort with sort({_id:1}) and reverse the results array, but i feel it like a hack...
Am I missing something obvious??
Thanks in advance
Upvotes: 1
Views: 2035
Reputation: 51
I have solved it this way. Please comment if you have any better solution.
// import ObjectId from mongodb
let sortOrder = -1;
let query = []
if (prev) {
sortOrder = 1
query.push({title: 'findTitle', _id:{$gt: ObjectId('_idValue')}})
}
if (next) {
sortOrder = -1
query.push({title: 'findTitle', _id:{$lt: ObjectId('_idValue')}})
}
db.collection.find(query).limit(10).sort({_id: sortOrder})
Upvotes: 1
Reputation: 11671
To paginate with a sort, you remember the highest entry of the previous page in order to return the next 10 results. For example, to paginate on the following collection
> for (var i = 0; i < 100; i++) db.page.insert({ "x" : i })
you do the following
> var page = db.page.find().sort({ "x" : 1 }).limit(10)
// do stuff with the page and get the highest `x`
> var max_x = page.toArray()[9].x
> var next_page = db.page.find({ "x" : { "$gt" : max_x } }).sort({ "x" : 1 }).limit(10)
so there's a mapping max_x
=> page
, i.e. given a max_x
you can get the right page since max_x
tells you the smallest value of x
not on the page. So just remember the previous page's max_x
(lower limit of the x
for the docs on the page) and you can recall the page.
Upvotes: 0