4

I'm having a hard time getting my head around CouchDB's linked documents feature.

I have two types of data being stored in a single CouchDB database:

{
  "id":"1",
  "type": "track",
  "title": "Bohemian Rhapsody"
}

{
  "id":"2",
  "type": "artist",
  "name": "Queen",
  "tracks": ["1"]
}

I'm under the impression that I can write a view like the one below and get the following documents emited:

{
  "id":"2",
  "type": "artist",
  "name": "Queen",
  "tracks": [
    {
      "id":"1",
      "type": "track",
      "title": "Bohemian Rhapsody"
    }
  ]
}

I've been trying this view, but it's not working the way I'm expecting:

function(doc) {
  if(doc.type == 'artist') {
    var tracks = [];
    for(var i = 0; i < doc.tracks.length; i++) {
      tracks.push({_id:doc.tracks[i]});
    }

    newdoc = eval(uneval(doc));
    newdoc.tracks = tracks;

    emit(doc._id,newdoc);
  }
}

example here: http://jphastings.iriscouch.com/_utils/database.html?music/_design/test/_view/linked

This isn't returning what I'd hope - do you have any suggestions? Thanks

JP.
  • 5,507
  • 15
  • 59
  • 100
  • I don't think that it's possible this way.In views a document is processed one at a time.So if id1 and id2 are 2 documents first id1 will be processed and then id 2. – Akshat Jiwan Sharma Jan 30 '13 at 10:37
  • 1
    I added a design document (dominicbarnes) with a view ([linked](http://jphastings.iriscouch.com/music/_design/dominicbarnes/_view/linked?include_docs=true)) Notice the addition of `include_docs=true`. The view itself is heavily commented. – Dominic Barnes Jan 30 '13 at 16:58
  • Also, I added `_count` as the reduce function, using that with `group_level=1` shows you how many documents are listed with each artist/collection. – Dominic Barnes Jan 30 '13 at 17:02

1 Answers1

5

Okay I finally understand what you are trying to do.Yes this is possible.Here is how.

You have 2 documents

{
"_id":"anyvalue",
"type": "track",
"title": "Bohemian Rhapsody"
}

{
"_id":"2",
"type": "artist",
"name": "Queen",
"tracks": ["anyvalue"]
}

What you were doing wrong was not having quotes around the value of tracks(the item in the array).

2)The reference id must be _id for this to work.The difference is worth noting since you can have id field but only _id are used to identify documents.

For the result you want this view would suffice

function(doc) {
    if (doc.type === 'artist') {
        for (var i in doc.tracks) {
            var id = doc.tracks[i];
            emit(id, { _id: id });
        }
    }
}

What you want to be doing is use an emit function inside the for loop to emit the id field of the 'track' of every artist.

Then you want to query couch db view with the include_docs=true parameter.Here is the final result for the database that you created on iris couch.

http://jphastings.iriscouch.com/music/_design/test/_view/nested?reduce=false&include_docs=true

 {
"total_rows": 3,
"offset": 0,
"rows": [
 {
  "id": "0b86008d8490abf0b7e4f15f0c6a50a7",
  "key": "0b86008d8490abf0b7e4f15f0c6a463b",
  "value": {
    "_id": "0b86008d8490abf0b7e4f15f0c6a463b"
  },
  "doc": {
    "_id": "0b86008d8490abf0b7e4f15f0c6a463b",
    "_rev": "3-7e4ba3bfedd29a07898125c09dd7262e",
    "type": "track",
    "title": "Boheniam Rhapsody"
  }
},
{
  "id": "0b86008d8490abf0b7e4f15f0c6a50a7",
  "key": "0b86008d8490abf0b7e4f15f0c6a5ae2",
  "value": {
    "_id": "0b86008d8490abf0b7e4f15f0c6a5ae2"
  },
  "doc": {
    "_id": "0b86008d8490abf0b7e4f15f0c6a5ae2",
    "_rev": "2-b3989dd37ef4d8ed58516835900b549e",
    "type": "track",
    "title": "Another one bites the dust"
  }
},
{
  "id": "0b86008d8490abf0b7e4f15f0c6a695e",
  "key": "0b86008d8490abf0b7e4f15f0c6a6353",
  "value": {
    "_id": "0b86008d8490abf0b7e4f15f0c6a6353"
  },
  "doc": {
    "_id": "0b86008d8490abf0b7e4f15f0c6a6353",
    "_rev": "2-0383f18c198b813943615d2bf59c212a",
    "type": "track",
    "title": "Stripper Vicar"
  }
 }
]
}

Jason explains it wonderfully in this post

Best way to do one-to-many "JOIN" in CouchDB

this link is also helpful for entity relationships in couch db

http://wiki.apache.org/couchdb/EntityRelationship

Community
  • 1
  • 1
Akshat Jiwan Sharma
  • 15,430
  • 13
  • 50
  • 60
  • Thanks for the pointer on the quote marks, I think that was just haste typing into Stackoverflow! I'm not sure I follow your second answer though. I've made an account, but it's not been set up yet it seems. – JP. Jan 30 '13 at 12:36
  • If you want to see futon you have to go to a url like this http:\\username.iriscouch.com/_utils/index.html.Where as you database is http://username.irisouch.com – Akshat Jiwan Sharma Jan 30 '13 at 12:49
  • Here's the data above (and a second example) in an iriscouch: http://jphastings.iriscouch.com/_utils/database.html?music/_design/test/_view/linked – JP. Jan 30 '13 at 13:59