incubator-couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Hammond <skippy.hamm...@gmail.com>
Subject Re: How to get nested-key-sorted collection of documents
Date Sun, 22 Nov 2009 21:58:04 GMT
On 22/11/2009 11:33 PM, Szymon Kapeniak wrote:
> Now I want to retrieve from couchdb list of documents sorted by many
> nested keys. What I need at the end is like a python dictionary with
> above records as keys, and doc _ids as values. The point is to make it
> nest-able with arbitrary order of keys . Ideally this would be all
> done by couchdb not client. But I'm not sure if it's possible.

Instead of trying to get all _ids as values, you just let lots of rows 
come back and merge them client side.

>
> Simplest view can be seen like:
>
> author:
> - Tolstoj :  list of  _ids
> - Goethe:  list of _ids
> - Blake:    list of  _ids
>
> this is easy one, but I need:
>
> author:
> - Tolstoj : 1985: list of _ids
>                : 1992: list of _ids
> - Goethe : ...

Here your map function looks something like:

emit([doc.author, doc.date], null);

Your rows will then be returned, with the _id, in order of author and 
date.  You could query like:

startkey=["Tolstoj", 1985], endkey=["Tolstoj", 1999]

To query a range of dates for a single author.

> and even more:
>
> author:
> - Tolstoj:  1985: publisher: X: list of _ids
>                                           : Y: list of _ids
>               :  1992: ...
>
> - Goethe: 1950:

Very similar:

emit([doc.author, doc.date, doc.publisher], null);

By using the group_level capability (see the wiki about the view API), 
you could still search just by author, by author and date, or by all 3 
fields.

> and also in reverse:
>
> author:
> - Tolstoj:  publisher : X: 1985: list of _ids
>                                       :1992: list of _ids

This one would be similar, but would use a different view which changes 
the order the keys are emitted.  Or with some extra tricks you probably 
could reuse the same view.

Then you should look at the Python 'itertools' module, and specifically 
the 'groupby' function - this will make it trivial to combine multiple 
rows with the same key prefix (eg, with the same author) quite easy to 
work with.  Something like:

for author, row_iter in itertools.groupby(rows, lambda r: r['key'][0]):
   print "Author", key, "has the following rows:"
   for row in row_iter:
     print row

Should group all records with the same first key element - ie, the 
'author' in the examples above.

HTH,

Mark

Mime
View raw message