jlb333333
jlb333333

Reputation: 371

Grouping the output of a CouchDB View

I have a map reduce view:

.....

emit( diffYears, doc.xyz );

reduced with _sum.

xyz is then a number which is summed per integer(diffYears).

The output looks roughly like this:

4                       1204.9
5                       796.19
6                       1124.8
7                       1112.6
8                       1993.62                     
9                       159.26
10                      395.41
11                      456.05
12                      457.97
13                      39.80
14                      483.68
15                      269.469
etc..

What I would like to do is group the results as follows:

Grouping                Total per group
0-4                     1959.2      i.e add up the xyz's for years 0,1,2,3,4
5-9                     3998.5      same for 5,6,7,8,9    ...etc.
10-14                   3566.3

I saw a suggestion where a list was used on a view output here: Using a CouchDB view, can I count groups and filter by key range at the same time? but have been unable to adapt it to get any kind of result. The code given is:

{
_id: "_design/authors",
views: {
authors_by_date: {
  map: function(doc) {
    emit(doc.date, doc.author);
  }
}
},
lists: {
count_occurrences: function(head, req) {
  start({ headers: { "Content-Type": "application/json" }});

  var result = {};
  var row;
  while(row = getRow()) {
    var val = row.value;
    if(result[val]) result[val]++;
    else result[val] = 1;
  }
  return result;
}
}
}

I substituted var val = row.key in this section:

    while(row = getRow()) {
    var val = row.value;
    if(result[val]) result[val]++;
    else result[val] = 1;
    }

(although in this case the result is a count.)

This seems to be the way to do it.

(It is like having a startkey and endkey for each grouping which I can do manually, naturally, but not inside a process. Or is there a way of entering multiple start- and endkeys into one GET command???? )

This must be a fairly normal thing to do especially for researchers using statistical analysis.

I assume therefore that it does get done but I cannot locate examples as far as CouchDB is concerned.

I would appreciate some help with this please or a pointer in the right direction.

Many thanks.

EDIT: Perhaps the answer lies in a process in 'reduce' to group the output??

Upvotes: 1

Views: 178

Answers (1)

sarwar
sarwar

Reputation: 2845

You can accomplish what you want using a complex key. The limitation is that the group size is static and needs to be defined in the view.

You'll need a simple step function to create your groups within map like:

var size = 5;  
var group = ( doc.diffYears  - (doc.diffYears % size)) / size;
emit( [group, doc.diffYears], doc.xyz);

The reduce function can remain _sum.

Now when you query the view use group_level to control the grouping. At group_level=0, everything will be summed and one value will be returned. At group_level=1 you'll receive your desired sums of 0-4, 5-9 etc. At group_level=2 you'll get your original output.

Upvotes: 1

Related Questions