views:

75

answers:

2

I'm creating a page system using CouchDB, showing:

  • 10 items per page
  • a link to the previous page (if any)
  • a link to the next page (if any)

From this article on the topic, I understand that using skip is suboptimal, and that I should instead use the startkey property to specify the first document, read 11 documents from there, display the first 10 and use the key of the 11th to display the link to the next page. What troubles me is the link to the previous page. The article says:

Populating the link to the previous page is as simple as carrying the current startkey over to the next page. If there’s no previous startkey, we are on the first page.

This works when going to the next page: when I move from page 4 to page 5 I can remember that the previous page was 4. But when I move back from page 5 to page 4, I have no way of carrying over the startkey of page 3. How can this work?

Is it possible (and recommended) to use endkey along with skip=10 and limit=1 to find the first element on the previous page, so that I may create a link back to it?

A: 

Read 21 documents instead of 11 - One extra going forward, and ten going backwards. The very first one holds the key to the previous page.

Core Xii
+1  A: 

You can in fact only ask for 11 documents, and that is what Futon does (look at CouchDB logs).

The trick

In fact, both the next and previous page work the same way: startkey becomes the first or last element, with a skip=1 to avoid overlapping. You just have to correctly use the descending parameter to get previous documents or next documents.

The execution

Whenever you're asking for a page, CouchDB answers with ten documents. Let's say the key of the first one is first and the key of the last one is last. The pagination links will look like:

"next": /db/_view/myview?descending=true&limit=11&startkey=last&skip=1
"back": /db/_view/myview?descending=false&limit=11&startkey=first&skip=1

Et voilà! You just have to reverse the documents when descending=false. Finding your data with views explains nicely the relation between those parameters, such as descending, and B-Trees.

Bonus

You can easily get the docid of the first or last page (limit=1 and descending true or false), and get a pagination system that looks a lot like something you would have with a classical database (first, last, previous, next).

Cygal