How To work with values at reduce functions?

Hey,

I am trying to learn how to use map reduce functions with couch base. until now i created reports engines based on SQL using Where with multi terms (adding and subtracting terms) and to modify the group part.

I am trying to create this report engine using views.

my problem is how to create a report that enable users to dive in and find more and more data, getting all the way to individual ip stats.
For example. how many clicks where today ? which traffic source ? what did they see? which country ? and etc..

My basic doc for this example look like this:

"1"
{
"date": "2014-01-13 10:00:00",
"ip": "111.222.333.444",
"country": "US",
"source":"1",
}
"2"
{
"date": "2014-01-13 10:00:00",
"ip": "555.222.333.444",
"country": "US",
"source":"1",
}
"3"
{
"date": "2014-01-13 11:00:00",
"ip": "111.888.888.888",
"country": "US",
"source":"2",
}
"4"
{
"date": "2014-01-13 11:00:00",
"ip": "111.777.777.777",
"country": "US",
"source":"1",
}

So i want to allow the user to see at the first screen , how many clicks per day there are at this site.
so i need to count the amount of clicks. simple map/reduce:
MAP:
function (doc, meta) {
emit(dateToArray(doc.date),1);
}
Reduce:
_count

group level 4, group true

will create the sum of clicks per hour.

Now if i want to allow a break down of countries, so i need a dynamic param to change.. from what i am understand it can only by the group level..
so assume i have added this to the emit like this:

emit([dateToArray(doc.date),source],1);

and then grouping level 5 will allow this divide, and using the key too focus on a certein date.. but what if i need to add a county break down? adding this to the emit again?
this seem to be a mess, also if i will want to do a country stats before the source.. is there any smarter way to do this?

Second part...

What if i want to get the first count as follow:

[2014,1,28,10] {ip:"555.222.333.444","111.222.333.444","count":"2"}

i want to see all the ips that are counted for this time...
how should i write my reduce function?

this is my current state that doesnt work..

function(key, values, rereduce) {
var result = {id: 0, count: 0};
for(i=0; i < values.length; i++) {
if(rereduce) {
result.id = result.id + (values[i]).ip +',';
result.count = result.count + values[i].count;
} else {
result.id = values.ip;
result.count = values.length;
}
}
return result;

i didnt get the answer format i was looking for..

i hope this is not to messy and that you could help me with this..

thanks!!

}

1 Answer

« Back to question.

Try using the Elasticsearch plugin.
Store the json docs in couchbase and XDCR the doc to ElasticSearch. In ElasticSearch you can do ad-hoc and very complex queries better then SQL.
Elasticsearch will bring back a json list of couchbase keys.
In the couchbase SDK do a BulkGet(array_of_keys_in_couchbase) BOOM under a 1 millisecond.

Remember to do not have Elasticsearch store the whole doc or else the rest response from Elasticsearch will kill your speed.

You can get the plugin here http://docs.couchbase.com/couchbase-elastic-search/