Rakesh VK
Rakesh VK

Reputation: 11

Creating a list of tags using couchDB map reduce

I've a list of documents (operators) and they have devices. Each of these devices has or more more tags. I want to create a unique list of tags for each operator.

Operator1: Device1 tag_1 tag_2 Device2 tag_1 tag_3

Operator2: Device1 tag_4 tag_2 Device2 tag_1 tag_3

I want the output to be like

    Operator1 -> Tags: [tag_1,tag_2,tag_3]
    Operator2 -> Tags: [tag_1,tag_2,tag_3,tag_4]

How do I do this using a view (map reduce) ? I was able to emit the documents using the below mapper.

    function(doc) {
        if (doc.key && doc.operator && doc.tags) {
            for (tag in doc.tags) {
              emit(doc.operator, tag.toLowerCase());
            }
         }
    }

This emits

    Key           Value
    Operator1 - > tag_1
    Operator1 - > tag_2
    Operator1 - > tag_1
    Operator1 - > tag_3
    Operator2 - > tag_1
    Operator2 - > tag_2
    Operator2 - > tag_3
    Operator2 - > tag_4

I couldn't figure how to group them to:

    Operator1 -> Tags: [tag_1,tag_2,tag_3]
    Operator2 -> Tags: [tag_1,tag_2,tag_3,tag_4]

Upvotes: 1

Views: 280

Answers (2)

amaurel
amaurel

Reputation: 41

Add a reduce function.

function(keys, values) {
   return sum(values);
}

Then query with the parameter group=true.

Upvotes: 0

Dominic Barnes
Dominic Barnes

Reputation: 28439

You can use a reduce function to accomplish this:

function (keys, values, rereduce) {
  var tags = {};
  values.forEach(function(tag) {
    if (!tags[tag]) tags[tag] = true;
  });
  return Object.keys(tags).sort();
}

This will iterate the values (ie: "tags") and return a unique list of them.

Generally speaking, reduce functions are supposed to have very small output, like simple numbers. Depending on how large and diverse your dataset is, you may need to configure your server to allow larger reduce output.

Upvotes: 2

Related Questions