1

In my couch I have document pairs like this:

{
  _id: "DOCID",
  type: "Task",
  info: { k1: "v1", k2: "v2" }
}
{ 
  _id: "ANOTHER DOCID",
  type: "Final",
  task: "DOCID",
  author: "Authorname"
}

For an author, several of these pairs can exist.

I now need a view which will give me the information coupled in a way, that the author is accompanied by the info.

Using view collocation I created the following view:

function(doc) {
  if (doc.doc_type == "Final")
    emit([doc.task, 0], doc.author);
  if (doc.doc_type == "Task")
    emit([doc._id, 1], doc.definition);
}

And I get results like these:

["153b46415108e95c811e1d4cd018624f", 0] -> "Authorname"
["153b46415108e95c811e1d4cd018624f", 1] -> { info here }

First, I used a reduce function to incorporate both into one, but after timing it, grouping them locally is way faster.

However, the way it is now, I cannot query this view by the "Authorname". Especially not because the info does not come with an Authorname.

So there are some solutions to this I think:

  1. Use a reduce function with grouping and manipulate the key so it shows the author (I dont even know if manipulating a grouped key is possible)
  2. Get all the rows, group them locally, and filter for the Author I am looking for (probably too much unwanted overhead)
  3. Have multiple views and perform 2 queries. One to get the DOCIDs and then query for the DOCIDs.
  4. Query the collocated view smartly: include the Authorname into the key and kind of query that in an efficient way, but I also don't think this is possible, as a query for Authorname will exclude the the actual info.

So what would you recommend to go on about this? And yes there is a reason for why the information is separate (several Final docs can be related to the same Task document, hence having the same information)

Best

Edit The provided solution, does answer my question, but I went for using my view and grouping the results in my code (a Django View) which turned out to be really fast!

enpenax
  • 1,476
  • 1
  • 15
  • 27

1 Answers1

0

I now need a view which will give me the information coupled in a way, that the author is accompanied by the info.

So if I understand correctly the requirements are

  1. The view should be queried by the author name.

  2. The output results should be the name of the author and the INFO document.

Well your documents are structured perfectly to support linked document retrieval

I think this map function should do it

function(doc) {

if(doc.author){
  emit(doc.author,{_id:doc.task});

}

if I query it with the include_docs=true here is the result I get

 {
  total_rows: 1,
  offset: 0,
  rows: [
    {
      id: "19ae88d060834dafdea9417384e2db20",
      key: "Authorname",
      value: { _id: "DOCID" },
      doc: {
        _id: "DOCID",
        _rev: "1-d7fe42dd7858238bb2d1112abf24f046",
        type: "Task",
        info: { k1: "v1", k2: "v2" }
      }
    }
  ]
}

About reduce from the couchdb wiki

A reduce function must reduce the input values to a smaller output value. If you are building a composite return structure in your reduce, or only transforming the values field, rather than summarizing it, you might be misusing this feature

Edit based on comment:-

Since the task document is too big and you don't want to fetch it all there are two approaches that you can take

  1. Embed the info directly in the author. Since all you want from task is the info part. Couchdb and other no sql databases encourage de-normalization of data for ease of access.

  2. Use list function to modify the large json output into a format that will be usable by you.

Akshat Jiwan Sharma
  • 15,430
  • 13
  • 50
  • 60
  • Thanks for teaching me about that! You might consider fixing your view code. However, I try to avoid fetching the whole Task document, as it contains a lot of data, that I do not want to fetch, as for this case its not useful and slow. Hence, I need to take a more complicated approach. – enpenax Jun 25 '14 at 06:01
  • @user2033511 can you check if the edited answer solves your problem. – Akshat Jiwan Sharma Jun 25 '14 at 06:24
  • It kind of does, but I went now with an approach of using my view and filter the output manually, which turned out to be 10x faster (in my case). So I will accept your answer, as it does indeed answer the question, but for my particular case I found a solution – enpenax Jun 25 '14 at 09:04