3

I have a question, i have 2 kind of documents, one of them is like this:

{
  "type": "PageType",
  "filename": "demo"
  "content": "zzz"
}

and another one like this:

{
  "type": "PageCommentType",
  "refFilename": "demo"
  "content": "some comment content"
}

i need to emit document that contains .comments field which is array of PageCommentType documents that i link on condition PageType document filename == PageCommentType document refFilename fields.

{
  "filename": "demo",
  "comments": [{}, {}, {}]
}

Anyone has any suggestions on how to implement it?

Thank you.

1 Answers1

4

You need view collation. Emit both within the same view, using the filename as the key and a type identifier to discriminate between comments and the original content:

function(doc) {
  if (doc.type == "PageType") emit([doc.filename,0],doc.content);
  if (doc.type == "PageCommentType") emit[doc.refFilename,1],doc.content);
}

When looking for the document demo and its comments, run a query with startkey=["demo",0] and endkey=["demo",1]: you will get the page content followed by all the comments.

Once you have all the data you want, but it's not in the right format, you are almost done. Simply write a _list function to read all the rows and output the final JSON document with the structure/schema that you need.

JasonSmith
  • 72,674
  • 22
  • 123
  • 149
Victor Nicollet
  • 24,361
  • 4
  • 58
  • 89
  • Did you mean `doc.comments` for the second `emit`? – Wayne Conrad Jan 24 '11 at 23:07
  • this two rows result i managed, but it's not what im looking for. i wanted to have aggregated document that has comments attribute which is array of documents emitted of type PageCommentType... in earlier versions of CouchDb as i recall there was some way to call map within map function and somehow wrap it, but i just can't figure out how it works now... – Evgenios Skitsanos Jan 24 '11 at 23:57
  • Sometimes if I hear "aggregated," that is a clue to **reduce** from the map/reduce views. Unfortunately, reducing is not going to work here because you are *accumulating* data rather than *reducing* it. (In other words, you'll get an error that the reduce size is too big.) I will amend Victor's answer with some ideas. – JasonSmith Jan 25 '11 at 03:23
  • Aggregation not necessary means what you had in mind, it's about collecting data and spitting it in certain format, this is why i was specific in my question on how i want to see my data, so Vistor's answer is not fitting here, because what he suggests will spit resultset like {"total_rows":4,"offset":0,"rows":[]} where rows array will have first element as my document of PageType and rest of the array items will be PageCommentType -- this is too simple, totally not what i'm looking for... – Evgenios Skitsanos Jan 25 '11 at 10:24
  • @Skitsanos: in that case, use a `_list` function as suggested by jhs' edit to transform the resultset into a more appropriate format. – Victor Nicollet Jan 25 '11 at 10:39