1
votes

I want to make search function that search all document containing specific tags using couchdb view.

Assume I have the following documents:

    {
          "_id": "1",
          "tags": ["abc", "acb", "abd"]
    }

    {
          "_id": "2",
          "tags": ["abc", "acb"]
    }

And my map function:

    function(doc) {
            for(var idx in doc.tags)
                    emit(doc.tags[idx], doc._id)
    }

when I want to find all documents which contains tags started with ab, i can use query parameter ?startkey="ab"&endkey="ab\u0999", and couchdb returned

    {"total_rows":5,"offset":0,"rows":[
            {"id":"1","key":"abc","value":"1"},
            {"id":"2","key":"abc","value":"2"},
            {"id":"1","key":"abd","value":"1"}
    ]}

How to make reduce function, so couchdb will return unique id from my view?

1
Do you want to obtain unique id-s for a single tag or for all tags? - Marcin Skórzewski
i want unique ids for all tags - Chito Adinugraha

1 Answers

3
votes

You should not do it in the reduce function because you cannot bound the size of the resulting id-s set. Anyway, reduce function is only useful when your calculations are "reusable". It does not calculate anything using the query parameters (eg. startkey and endkey), query just take what reduce have output before. In you case the range of the keys is arbitrary and reduce will not work easily :(

But, you can do it in the list function. I think that something like the following should work (not tested):

function(head, req){
  var ar = new Array();
  // get all the id-s
  while(row = getRow()){
    ar.push(row.value)
  }
  // make the result unique
  ar = ar.sort().filter(function (e, i, arr) {
    return arr.lastIndexOf(e) === i;
  });
  send(toJSON(ar));
}

It should produce the JSON array of unique id-s for the requested range. Note that format of the result is is not conformant to the CouchDB standard and if you use some high level API you will want to reformat the result a bit.