13

I have two documents that looks a bit like so:

Doc
{
  _id: AAA,
  creator_id: ...,
  data: ...
}

DataKey
{
  _id: ...,
  credits_left: 500,
  times_used: 0,
  data_id: AAA
}

What I want to do is create a view which would allow me to pass the DataKey id (key=DataKey _id) and get both the information of the DataKey and the Doc.

My attempt:

I first tried embedding the DataKey inside the Doc and used a map function like so:

function (doc)
{
  if (doc.type == "Doc")
  {
    var ids = [];
    for (var i in doc.keys)
      ids.push(doc.keys[i]._id);

    emit(ids, doc);
  }
}

But i ran into two problems:

  1. There can be multiple DataKey's per Doc so using startkey=[idhere...] and endkey=[idhere..., {}] didn't work (only worked if the key happend to be the first one in the array).
  2. All the data keys need to be unique, and I would prefer not making a seperate document like {_id = datakey} to reserve the key.

Does anyone have ideas how I can accomplish this? Let me know if anything is unclear.

-----EDIT-----

I forgot to mention that in my application I do not know what the Doc ID is, so I need to be able to search on the DataKey's ID.

Obto
  • 1,377
  • 1
  • 20
  • 33

1 Answers1

11

I think what you want is

function (doc)
{
  if (doc.type == "Doc")
  {
    emit([doc._id, 0], doc);
  }

  if(doc.type == "DataKey")
  {
    emit([doc.data_id, 1], doc);
  }
}

Now, query the view with key=["AAA"] and you will see a list of all docs. The first one will be the real "Doc" document. All the rest will be "DataKey" documents which reference the first doc.

This is a common technique, called CouchDB view collation.

JasonSmith
  • 72,674
  • 22
  • 123
  • 149
  • This does group them together, but I forgot to mention that in my application I do not know what the Doc ID is. So I need to be able to search on the DataKey's ID. – Obto Jun 17 '11 at 04:05
  • What about doing two queries then? First you get the Doc ID from the DataKey document. Then you query by Doc ID. – Marcello Nuccio Jun 17 '11 at 07:55
  • Right, it is very helpful to know the doc id, the easiest thing may be just to query and fetch them first. – JasonSmith Jun 17 '11 at 09:10
  • Well I was hoping to avoid making a second connection to the DB but it looks like that may be the only way to do so. – Obto Jun 17 '11 at 16:19
  • It doesn't have to be the `_id` field. It can be *any* identifier that is shared between both documents. In your example, "AAA" is in both so I wanted the view to put all "AAA" together (Doc and DataKey), thus AAB and AAC would be together, etc. Not sure if that is possible in your real application. – JasonSmith Jun 17 '11 at 23:57
  • Yeah the only way i could do that is by having the doc store all the datakeys's and have a map function that looped through each of the keys and emitted the key and itself. The problem I had with this is the size of that view grows really fast. – Obto Jun 18 '11 at 02:28