Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the CouchDB equivalent of the SQL COUNT(*) aggregate function?

Tags:

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?

like image 969
Brad Gessler Avatar asked Oct 19 '09 01:10

Brad Gessler


People also ask

What is COUNT aggregate function in SQL?

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.

Is CouchDB a SQL database?

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.

What are the 5 aggregate functions?

There are five aggregate functions, which are: MIN, MAX, COUNT, SUM, and AVG.

Which aggregate function is used to COUNT the number of rows in an SQL query?

Use the COUNT aggregate function to count the number of rows in a table.


2 Answers

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".

like image 123
David Coallier Avatar answered Oct 11 '22 12:10

David Coallier


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); } 
like image 37
Will Harris Avatar answered Oct 11 '22 11:10

Will Harris