MongoDB Pagination – using $slice

How to implement pagination in MongoDB using $slice
Another technique of implementing pagination in MongoDB involves the use of $push and $slice. In this method, we store the documents in an array and use the $slice method to accomplish what skip()-and-limit() does, but without the overhead associated with the skip() method.
We will be using a single root document in a collection with two fields: i. an array to store the sub-documents, ii. a numerical key to store the size of the array.
// Clear the collection of any previous data and create the root document
db.companies.drop()
db.companies.insert({items:[], count:0})

// Add the sub-documents to the root document
db.companies.update({}, {$push:{items:'Google'}})
db.companies.update({}, {$set:{count:1}})
db.companies.update({}, {$push:{items:'Facebook'}})
db.companies.update({}, {$set:{count:2}})
db.companies.update({}, {$push:{items:'Apple'}})
db.companies.update({}, {$set:{count:3}})
db.companies.update({}, {$push:{items:'Microsoft'}})
db.companies.update({}, {$set:{count:4}})
db.companies.update({}, {$push:{items:'Oracle'}})
db.companies.update({}, {$set:{count:5}})
db.companies.update({}, {$push:{items:'IBM'}})
db.companies.update({}, {$set:{count:6}})
db.companies.update({}, {$push:{items:'Yahoo'}})
db.companies.update({}, {$set:{count:7}})
db.companies.update({}, {$push:{items:'HP'}})
db.companies.update({}, {$set:{count:8}})
Now observe how the $slice operator works.
db.companies.find({}, {items:{$slice:[0, 3]}})
db.companies.find({}, {items:{$slice:[3, 3]}})
From the above commands you can see, you already have pagination in place. It just needs to be made dynamic, which is accomplished thus:
var skip = NUMBER_OF_ITEMS * (PAGE_NUMBER - 1)
db.companies.find({}, {$slice:[skip, NUMBER_OF_ITEMS]})
NUMBER_OF_ITEMS is the number of items to be shown on a page
PAGE_NUMBER is the current page number
For creating the pagination navigation links, use the count field to get the number of items and the number of pages.
Notes
  1. Items are no longer root documents
  2. Need to maintain a count key
  3. Data structure clarity and logic is somewhat lost

Comments