couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Goodall <matt.good...@gmail.com>
Subject Re: How can I resolve an external relation in embedded documents
Date Fri, 09 Jul 2010 11:33:10 GMT
On 9 July 2010 11:53, Alexander Thomas
<herr.alexander.thomas@googlemail.com> wrote:
> Hello everybody,
>
> my name is Alexander Thomas. I'm a freelance web developer from Vienna, Austria.
>
> After playing around with CouchDb a bit I finally decided to give it a try in a first
real life project. So in case my question is trivial, don't hesitate to RTFM me and give me
a (helpful) pointer.
>
> I have a document type called 'story'. A story can have multiple sections as embedded
documents, stored in an array.
>
> {
>   "_id": "story_14c2f7f84c9701",
>   "_rev": "4-abf15eac70a379c9a60b889c9e73357e",
>   "type": "story",
>   "title": "Untitled",
>   "modified": "2010-07-03 20:27:35",
>   "sections": [
>       {
>           "text": "test 1",
>           "author_id": id_of_author
>       },
>       {
>           "text": "test 2",
>           "author_id": id_of_author
>       }
>   ]
> }
>
> Each section may have a different author so I store authors in different documents to
avoid duplicates.
>
>
> Reading the available documentation I was able to connect the story itself to an author
but what I would like to have is a view, which collects one / all stories + the information
of the author for each embedded section.


Hi,

CouchDB includes a simple document linking mechanism. You could write
a view that emitted a row for the story, and a row for each section
author with value {"_id": id_of_author}. Then use an include_docs=true
option when querying the view to retrieve the story's doc and all
associated author docs. The view might look something like (untested):

    function(doc) {
      if (doc.type == 'story') {
        emit([doc._id, 'story'], doc._rev);
        var authors = {};
        for each (var section in doc.sections) {
          authors[section.author_id] = true;
        }
        for (var author in authors) {
          emit([doc._id, 'author'], {"_id": author});
        }
      }
    }

However, if you're fetching multiple stories at a time then it's quite
likely that the same author will be retrieved multiple times for
different stories. Also, include_docs=true is not free.

So, if that's not going to work for you then your options are:

1. Include the interesting author attributes in each section.
2. Make two calls to CouchDB - the 1st calls fetches the story or
stories you're interested in; the 2nd call fetches any authors that
appear in the stories you found.

Personally, I'd probably just accept that I need to make two calls.

Hope that helps.

- Matt

Mime
View raw message