You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Sho Fukamachi <sh...@gmail.com> on 2008/11/09 22:36:46 UTC
dual purpose filter/count views
Hi all,
This is probably a really simple question, but for some reason* I
can't figure it out.
(* reason is most like extreme dumbness on my part)
I've got a bunch of views where i have something like this:
get_all_by_field:
map: if (doc.type == 'my_doc') emit(doc.field, doc);
count_all_by_field:
map: if (doc.type == 'my_doc') emit(doc.field, 1);
reduce: function(keys, values) { return sum(values) }
That works fine, but seems like it could be more elegant ..
I thought I'd be "clever" and try to combine the two, so I could get
the "search" output by calling the map alone, and then getting the
count by turning on reduce, something like this:
map: function(doc) {
if (doc.type == 'my_doc') emit(doc.field, [doc, 1]);
}
reduce: function(keys, values) { return sum(values[1]) }
The idea being that if i turn off reduce, it outputs the docs I want,
but if I turn it on, I can just count the second element in the
emitted array.
But for some reason it doesn't work. I've tried the above, just
returning values[1], trying to sum values[0][1], etc. I either get
errors or nothing.
This is probably some really simple thing that I'm missing in my tired
state. Can anyone give me a hint as to what it is? : )
thanks!
Sho
Re: dual purpose filter/count views
Posted by Antony Blakey <an...@gmail.com>.
On 10/11/2008, at 8:06 AM, Sho Fukamachi wrote:
> Hi all,
>
> This is probably a really simple question, but for some reason* I
> can't figure it out.
>
> (* reason is most like extreme dumbness on my part)
>
> I've got a bunch of views where i have something like this:
>
> get_all_by_field:
>
> map: if (doc.type == 'my_doc') emit(doc.field, doc);
>
> count_all_by_field:
>
> map: if (doc.type == 'my_doc') emit(doc.field, 1);
> reduce: function(keys, values) { return sum(values) }
>
> That works fine, but seems like it could be more elegant ..
>
> I thought I'd be "clever" and try to combine the two, so I could get
> the "search" output by calling the map alone, and then getting the
> count by turning on reduce, something like this:
>
> map: function(doc) {
> if (doc.type == 'my_doc') emit(doc.field, [doc, 1]);
> }
> reduce: function(keys, values) { return sum(values[1]) }
In any case, this isn't valid logic - you need to do something like
theSum = 0;
for (var i in values)
theSum = theSum + values[i][1];
return theSum;
Antony Blakey
--------------------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
What can be done with fewer [assumptions] is done in vain with more
-- William of Ockham (ca. 1285-1349)
Re: dual purpose filter/count views
Posted by Antony Blakey <an...@gmail.com>.
On 10/11/2008, at 8:06 AM, Sho Fukamachi wrote:
> This is probably some really simple thing that I'm missing in my
> tired state. Can anyone give me a hint as to what it is? : )
The reduce function takes a third parameter, which is false when the
input to the reduce function is output from your map function, and
true when the input to the reduce function is output from previous
invocations of the reduce function. In your case you could do
something like this:
reduce: function(keys, values, rereduce) { if (rereduce) return
sum(values) else return sum(values[1]) }
When doing a re-reduce, keys will also be null.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
On the other side, you have the customer and/or user, and they tend to
do what we call "automating the pain." They say, "What is it we're
doing now? How would that look if we automated it?" Whereas, what the
design process should properly be is one of saying, "What are the
goals we're trying to accomplish and how can we get rid of all this
task crap?"
-- Alan Cooper
Re: dual purpose filter/count views
Posted by Sho Fukamachi <sh...@gmail.com>.
On 10/11/2008, at 9:01 AM, Chris Anderson wrote:
> Reduce:
>
> function(keys, values, rereduce) {
> if (rereduce) {
> return sum(values);
> } else {
> return values.length;
> }
> }
Cool idea, works nicely in this situation and very elegant. Thanks for
the tip!
Sho
> --
> Chris Anderson
> http://jchris.mfdz.com
Re: dual purpose filter/count views
Posted by Chris Anderson <jc...@apache.org>.
On Sun, Nov 9, 2008 at 1:36 PM, Sho Fukamachi <sh...@gmail.com> wrote:
> map: function(doc) {
> if (doc.type == 'my_doc') emit(doc.field, [doc, 1]);
> }
> reduce: function(keys, values) { return sum(values[1]) }
Anthony's second email has a working idea, but this is how I like to
do it. Will work for any map function, so you can drop the funny array
value from your map.
Reduce:
function(keys, values, rereduce) {
if (rereduce) {
return sum(values);
} else {
return values.length;
}
}
--
Chris Anderson
http://jchris.mfdz.com