Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CouchDB Map/Reduce to an array

I have a number of documents which look like this:

{userId: 123, msg:{ timestamp:123456, event:"actionA"} }

{userId: 123, msg:{ timestamp:123466, event:"actionB"} }

etc...

Map fn:

emit(doc.userId, [doc.msg])

Reduce fn:

return [].concat.apply([], vs)

These functions seem to do what I expect, so I'd thought I'd see output like:

Key: 123, Value: [{timestamp:123456, event:"actionA"}, {timestamp:123466, event:"actionB"}, ...etc...]

But, I am getting a reduce overflow error, "Reduce output must shrink more rapidly". Indeed, the couchdb docs say that "As a rule of thumb, the reduce function should reduce to a single scalar value." ... "CouchDB will give you a warning if you try to use reduce “the wrong way”".

So, I guess I'm using Couch MR the "wrong way". What would be the "right way" to do this kind of calculation?

like image 737
Matthew Gilliard Avatar asked Feb 18 '12 18:02

Matthew Gilliard


1 Answers

I've hit this too before. CouchDB likes tall lists, not fat lists. In other words, you can probably get what you want with keys in the view, and not reducing them to the same thing.

If you want to see all messages from a userId, you do not need a reduce function. Simply query your view with ?key=123. You will see all messages for that userId and there is no limit to the size.

If you are unhappy with the format (if you simply must change the JSON that couch sends you), then Simon's list function link is correct.

like image 108
JasonSmith Avatar answered Oct 08 '22 23:10

JasonSmith