2

I have a sample database in CouchDB with the information of a number of aircraft, and a view which shows the manufacturer as key and the model as the value.

The map function is

function(doc) {
    emit(doc["Manufacturer"], doc._id)
}

and the reduce function is

function(keys, values, rereduce){
    return values.length;
}

This is pretty simple. And I indeed get the correct result when I show the view using Futon, where I have 26 aircraft of Boeing:

"BOEING"    26

But if I use a REST client to query the view using

http://localhost:6060/aircrafts/_design/basic/_view/VendorProducts?key="BOEING"

I get

{"rows":[
    {"key":null,"value":2}
]}

I have tested different clients (including web browser, REST client extensions, and curl), all give me the value 2! While queries with other keys work correctly.

Is there something wrong with the MapReduce function or my query?

Weixiang Guan
  • 457
  • 2
  • 6
  • 16

2 Answers2

2

The issue could be because of grouping

Using group=true (which is Futon's default), you get a separate reduce value for each unique key in the map - that is, all values which share the same key are grouped together and reduced to a single value.

Were you passing group=true as a query parameter when querying with curl etc? Since it is passed by default in futon you saw the results like

BOEING : 26

Where as without group=true only the reduced value was being returned.

So try this query

http://localhost:6060/aircrafts/_design/basic/_view/VendorProducts?key="BOEING"&group=true

Akshat Jiwan Sharma
  • 15,430
  • 13
  • 50
  • 60
  • Thanks! This does indeed what I need. I am pretty new to CouchDB and there are things that I did not pay attention to. And using `group=true` also solves the problem with the `null` key, in which case although the value is correct, the key is always `null`. But now I am wondering, why do we need `group` and `reduce` two parameters? In which case is only `reduce` useful??? – Weixiang Guan Jun 29 '14 at 09:50
  • The difference is that `group` and `group_level` runs reduce for each set of unique keys where as reduce reduces the results to a single value. So in case you have another manufacturer like `ACME` the above query will return a result `BOEING:26,ACME:1` where as reduce will return `27`. So grouping in like running multiple reduces on keys. [More on wiki](http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Grouping). By the way I hope you are enjoying couchdb :) – Akshat Jiwan Sharma Jun 29 '14 at 10:00
  • Thanks again! I tried something with and without `group`, I think now I understand more about it. However, I still get a strange result when the key(s) contains "BOEING" and `group=false`, which is always 2, while the other results are correct. When `group=true`, the result is also correct. Maybe I have something wrong in my doc? Btw, I am using CouchDB 1.5, could it be a bug that was already fixed in 1.6? (Due to some unknown reason I was not successfully to make 1.6 work on my Windows 7). And I do enjoy CouchDB, and I want to go deep into it! – Weixiang Guan Jun 29 '14 at 18:35
1

You seem to be falling into the re-reduce-trap. Couchdb strictly speaking uses a map-reduce-rereduce process.

  • Map: reformats your data in the output format.
  • Reduce: aggregates the data of several (but not all entries with the same key) - which works correctly in your case.
  • Re-reduce: does the same as reduce, but on previously reduced data.

As you change the format of the value in the reduce stage, the re-reduce call will aggregate the number of already reduced values.

Solutions:

  1. You can just set the value in the map to 1 and reduce a sum of the values.
  2. You check for rereduce==true and in that case return a sum of the values - which will be the integer values returned by the initial reduce.
Hans
  • 2,800
  • 3
  • 28
  • 40
  • Thanks! I tried what you mentioned, and although I am 100% agreed with you, the result is almost the same. If I use your solution, I will get 26 Boeing aircraft no matter I use `group` or not, but all other aircraft are the same! That is, I get the same number of aircraft no matter I use `group` or not. It is pretty strange! But again, I agree 100% with your solution, and I will keep this mind! – Weixiang Guan Jun 29 '14 at 09:59