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