Yep, I'm a SQL jockey (sorta) coming into the CouchDb Map/Reduce world. I thought I had figured out how the equivalent of the COUNT(*) SQL aggregator function for CouchDB datasets with the following:
Map:
function(doc) { emit(doc.name, doc); }
Reduce:
function(keys, values, rereduce){ return values.length; }
Which I thought worked, returning something like:
"super fun C" 2 "super fun D" 2 "super fun E" 2 "super fun F" 18
... but not really. When I add a record, this count varies wildly. Sometimes the count actually decreases, which was very surprising. Am I doing something wrong? Maybe I don't fully understand the concept of eventual consistency?
An aggregate function in SQL performs a calculation on multiple values and returns a single value. SQL provides many aggregate functions that include avg, count, sum, min, max, etc. An aggregate function ignores NULL values when it performs the calculation, except for the count function.
Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang. CouchDB uses multiple formats and protocols to store, transfer, and process its data. It uses JSON to store data, JavaScript as its query language using MapReduce, and HTTP for an API.
There are five aggregate functions, which are: MIN, MAX, COUNT, SUM, and AVG.
Use the COUNT aggregate function to count the number of rows in a table.
In your reduce just put:
_count
You can also get a sum using:
_sum
so basically reduce: "_sum" or reduce: "_count" and make sure the value your map emits is a valid integer (numeric value)
See "Built in reduce functions".
It looks like your reduce results are being re-reduced. That is, reduce
is called more than once for each key and then called again with those results. You can handle that with a reduce
function like this:
function(keys, values, rereduce) { if (rereduce) { return sum(values); } else { return values.length; } }
Alternatively, you can change the map
function so that the values are always a count of documents:
// map function(doc) { emit(doc.name, 1); } // reduce function(keys, values, rereduce) { return sum(values); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With