Hey all,

I'd like to propose a small addition to the HTTP View API. I can open
a ticket later and maybe even submit a patch, but I want to discuss it
with y'all first.

This new View extension would get you a specified document (by the
View key) plus a few documents before and after it (with regards to
that View's sort order).

Say that calling this View:

    http://southparkelementary.edu/database/_design/students/_view/names

gives the following response (sorted by the key):

    {"total_rows":7,"offset":0,"rows":[
    {"id":"624","key":"broflovski","value":"Kyle Broflovski"},
    {"id":"928","key":"cartman","value":"Eric Cartman"},
    {"id":"848","key":"marsh","value":"Stan Marsh"},
    {"id":"433","key":"mccormick","value":"Kenny McCormic"},
    {"id":"855","key":"stotch","value":"Butters Stotch"},
    {"id":"489","key":"testaburger","value":"Wendy Testaburger"},
    {"id":"292","key":"vulmer","value":"Jimmy Vulmer"}
    ]}

Now, what I'd like to have is this:

    
http://southparkelementary.edu/database/_design/students/_view/names?key="mccormick"&diameter=1

which would return:

    {"total_rows":7,"offset":2,"rows":[
    {"id":"848","key":"marsh","value":"Stan Marsh"},
    {"id":"433","key":"mccormick","value":"Kenny McCormic"},
    {"id":"855","key":"stotch","value":"Butters Stotch"}
    ]}

(I'm not sure what's the best word for this query argument. Here are
some other suggestions: vicinity, surroundings, neighborhood, nearby)

Essentially, this combines two Views you can get by the clever use of
`startkey/endkey`, `limit` and `descending` arguments. The advantage
of this API addition is that it can be used in the CouchDB Lists.

The obvious use case are the previous/next links between document
pages. Following the example, if I had a web interface where the South
Park elementary teachers would view the pages of the students, it
would be nice if every student's page had a link to the previous and
next student along with their names and small photos. This means that
the List generating the student's page must have the access to the
previous and next documents in the given View.

For example getting a student's page:

    
http://southparkelementary.edu/database/_design/students/_list/student_page/names?key="mccormick"&diameter=1

would generate a similar HTML structure:

    <html>...<body>
    <h1>Student: Kenny McCormic</h1>
    ... (additional data)

    <img src="/database/848/photo.jpg" />
    <a 
href="/database/_design/students/_list/student_page/names?key="marsh"&diameter=1">previous:
Stan Marsh</a>

    <img src="/database/855/photo.jpg" />
    <a 
href="/database/_design/students/_list/student_page/names?key="stotch"&diameter=1">next:
Butters Stotch</a>
    </body></html>

As far as I can tell, there are two ways of doing that today:

a) client-side
b) add the linking logic directly to the documents in the database

The first option is not always feasible/desirable and I dislike the
second option because of its inflexibility. To maintain a
doubly-linked structure across the database means that changing a
single document could lead up to three separate document changes. And
the complexity raises if we want to have multiple ways of sorting.

However, this extension directly plays into the strength of Views,
which is that you can have the same set of standalone documents sorted
by several different rules. You can use this in Lists to generate
linked pages by different sorting rules.

It would also play nicely with the URL rewriting mechanisms, because
if a list can access the previous/next documents, it can use their
contents to generate the pretty URLs that are the rave these days.

I have limited knowledge of the CouchDB internals, but from what I
know, it doesn't look like a big problem. As the views are B+trees,
the leafs form a linked list already. I'm also guessing that the list
is in fact doubly-linked (the presence of the `descending` View
argument suggests so). Therefore, this change could be just a matter
of finding the document requested by the key and traversing the list
in both directions.

Please let me know what you think. Suggestions about the naming and
behaviour of the API call are welcome. In the meantime, I'll dive into
the CouchDB source and try to figure out how to implement this. I've
never programmed in Erlang, though -- it's probably going to take a
while.

With respect for your awesome work,
Tomas Sedovic

Reply via email to