You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by David Park <da...@points.com> on 2018/06/13 17:13:04 UTC

couchdb erlang reduce - aggregate object

Say I have a map that emits the following object:

>>> {"basePoints": 2000, "bonusPoints": 1000}
>>> {"basePoints": 1000, "bonusPoints": 50}
>>> {"basePoints": 10000, "bonusPoints": 5000}

How could I write a reduce in Erlang that would return an aggregate object
like this:

>>> {"basePoints": 13000, "bonusPoints": 6050}

(I would rather not have to write 2 separate views that emit each value
separately if i can help it)

Thanks!

David Park   Software Developer

M 416*.*461*.*2649

*Points  *|  More together.

Connect with us: Points <http://l.points.com/69s8/> | Twitter
<http://l.points.com/uxlj/> | Blog <http://l.points.com/vu4y/> | LinkedIn
<http://l.points.com/rjs4/> | Careers <http://l.points.com/juqh/>

TSX: PTS <http://l.points.com/sgf7/>; NASDAQ: PCOM
<http://l.points.com/ko1o/>

111 Richmond St W., Suite 700, Toronto, ON, M5H 2G4, Canada

Connect with me: LinkedIn <https://www.linkedin.com/in/butterdave>

Re: couchdb erlang reduce - aggregate object

Posted by David Park <da...@points.com>.
Thank you Aurelien, that works!

David Park   Software Developer

M 416*.*461*.*2649

*Points  *|  More together.

Connect with us: Points <http://l.points.com/69s8/> | Twitter
<http://l.points.com/uxlj/> | Blog <http://l.points.com/vu4y/> | LinkedIn
<http://l.points.com/rjs4/> | Careers <http://l.points.com/juqh/>

TSX: PTS <http://l.points.com/sgf7/>; NASDAQ: PCOM
<http://l.points.com/ko1o/>

111 Richmond St W., Suite 700, Toronto, ON, M5H 2G4, Canada

Connect with me: LinkedIn <https://www.linkedin.com/in/butterdave>



On Wed, Jun 13, 2018 at 3:41 PM Aurélien Bénel <au...@utt.fr>
wrote:

> Dear David,
>
> > I desire that value to be split out by base and bonus points.
>
> Then you’ll need an array as the key: a first member for the selection and
> a second one for the grouping.
>
>
> MAP :
>
> function(o) {
>    emit( [o.label, "base"] , o.basePoints);
>    emit( [o.label, "bonus"], o.bonusPoints);
> }
>
> REDUCE
>
> _sum
>
> QUERY
>
> ?group=true&startkey=["gold"]&endkey=["gold",{}]
>
>
> Regards,
>
> Aurélien
>
>
> > Début du message réexpédié :
> >
> > De: David Park <da...@points.com>
> > Objet: Rép : couchdb erlang reduce - aggregate object
> > Date: 13 juin 2018 à 20:17:19 UTC+2
> > À: user@couchdb.apache.org
> > Répondre à: user@couchdb.apache.org
> >
> > ok. so here's my test
> >
> > 3 docs
> >
> > {"_id": "a", "label": "gold", "basePoints": 1000, "bonusPoints": 2000}
> > {"_id": "b", "label": "gold", "basePoints": 10000, "bonusPoints": 20000}
> > {"_id": "c", "label": "silver", "basePoints": 10000, "bonusPoints":
> 20000}
> >
> > Then I took your advice and wrote a javascript (not erlang) view
> >
> > function(o) {
> >    emit(o.label, o.basePoints);
> >    emit(o.label, o.bonusPoints);
> > }
> >
> > then threw in a reduce of
> >
> > _sum
> >
> > then I queried my view with group = true where key = label
> > And I get a response of
> > {
> >  "rows":[
> >    {"key":"gold","value":33000}
> >  ]
> > }
> >
> > I desire that value to be split out by base and bonus points.
> >
> > David Park   Software Developer
>

Re: couchdb erlang reduce - aggregate object

Posted by Adam Kocoloski <ko...@apache.org>.
Hi David we added that in version 2.0:

https://github.com/apache/couchdb/commit/5a2ec4f50 <https://github.com/apache/couchdb/commit/5a2ec4f50>

The behavior is documented on master:

http://docs.couchdb.org/en/master/ddocs/ddocs.html#reduce-and-rereduce-functions <http://docs.couchdb.org/en/master/ddocs/ddocs.html#reduce-and-rereduce-functions>

Cheers, Adam

> On Jun 13, 2018, at 4:59 PM, David Park <da...@points.com> wrote:
> 
> hey robert, _sum doesn't work on objects :(
> 
> David Park   Software Developer
> 
> M 416*.*461*.*2649
> 
> *Points  *|  More together.
> 
> Connect with us: Points <http://l.points.com/69s8/> | Twitter
> <http://l.points.com/uxlj/> | Blog <http://l.points.com/vu4y/> | LinkedIn
> <http://l.points.com/rjs4/> | Careers <http://l.points.com/juqh/>
> 
> TSX: PTS <http://l.points.com/sgf7/>; NASDAQ: PCOM
> <http://l.points.com/ko1o/>
> 
> 111 Richmond St W., Suite 700, Toronto, ON, M5H 2G4, Canada
> 
> Connect with me: LinkedIn <https://www.linkedin.com/in/butterdave>
> 
> 
> 
> On Wed, Jun 13, 2018 at 3:58 PM Robert Samuel Newson <rn...@apache.org>
> wrote:
> 
>> the built-in reduce ("_sum") handles both arrays and objects, so you
>> should be able to just do;
>> 
>> map:
>> function(doc) {
>>  emit(doc.label, {"base":doc.basePoints, "bonus":doc.bonusPoints});
>> }
>> 
>> reduce:
>> _sum
>> 
>> B.
>> 
>>> On 13 Jun 2018, at 20:40, Aurélien Bénel <au...@utt.fr> wrote:
>>> 
>>> Dear David,
>>> 
>>>> I desire that value to be split out by base and bonus points.
>>> 
>>> Then you’ll need an array as the key: a first member for the selection
>> and a second one for the grouping.
>>> 
>>> 
>>> MAP :
>>> 
>>> function(o) {
>>>  emit( [o.label, "base"] , o.basePoints);
>>>  emit( [o.label, "bonus"], o.bonusPoints);
>>> }
>>> 
>>> REDUCE
>>> 
>>> _sum
>>> 
>>> QUERY
>>> 
>>> ?group=true&startkey=["gold"]&endkey=["gold",{}]
>>> 
>>> 
>>> Regards,
>>> 
>>> Aurélien
>>> 
>>> 
>>>> Début du message réexpédié :
>>>> 
>>>> De: David Park <da...@points.com>
>>>> Objet: Rép : couchdb erlang reduce - aggregate object
>>>> Date: 13 juin 2018 à 20:17:19 UTC+2
>>>> À: user@couchdb.apache.org
>>>> Répondre à: user@couchdb.apache.org
>>>> 
>>>> ok. so here's my test
>>>> 
>>>> 3 docs
>>>> 
>>>> {"_id": "a", "label": "gold", "basePoints": 1000, "bonusPoints": 2000}
>>>> {"_id": "b", "label": "gold", "basePoints": 10000, "bonusPoints": 20000}
>>>> {"_id": "c", "label": "silver", "basePoints": 10000, "bonusPoints":
>> 20000}
>>>> 
>>>> Then I took your advice and wrote a javascript (not erlang) view
>>>> 
>>>> function(o) {
>>>>  emit(o.label, o.basePoints);
>>>>  emit(o.label, o.bonusPoints);
>>>> }
>>>> 
>>>> then threw in a reduce of
>>>> 
>>>> _sum
>>>> 
>>>> then I queried my view with group = true where key = label
>>>> And I get a response of
>>>> {
>>>> "rows":[
>>>>  {"key":"gold","value":33000}
>>>> ]
>>>> }
>>>> 
>>>> I desire that value to be split out by base and bonus points.
>>>> 
>>>> David Park   Software Developer
>> 
>> 


Re: couchdb erlang reduce - aggregate object

Posted by David Park <da...@points.com>.
hey robert, _sum doesn't work on objects :(

David Park   Software Developer

M 416*.*461*.*2649

*Points  *|  More together.

Connect with us: Points <http://l.points.com/69s8/> | Twitter
<http://l.points.com/uxlj/> | Blog <http://l.points.com/vu4y/> | LinkedIn
<http://l.points.com/rjs4/> | Careers <http://l.points.com/juqh/>

TSX: PTS <http://l.points.com/sgf7/>; NASDAQ: PCOM
<http://l.points.com/ko1o/>

111 Richmond St W., Suite 700, Toronto, ON, M5H 2G4, Canada

Connect with me: LinkedIn <https://www.linkedin.com/in/butterdave>



On Wed, Jun 13, 2018 at 3:58 PM Robert Samuel Newson <rn...@apache.org>
wrote:

> the built-in reduce ("_sum") handles both arrays and objects, so you
> should be able to just do;
>
> map:
> function(doc) {
>   emit(doc.label, {"base":doc.basePoints, "bonus":doc.bonusPoints});
> }
>
> reduce:
> _sum
>
> B.
>
> > On 13 Jun 2018, at 20:40, Aurélien Bénel <au...@utt.fr> wrote:
> >
> > Dear David,
> >
> >> I desire that value to be split out by base and bonus points.
> >
> > Then you’ll need an array as the key: a first member for the selection
> and a second one for the grouping.
> >
> >
> > MAP :
> >
> > function(o) {
> >   emit( [o.label, "base"] , o.basePoints);
> >   emit( [o.label, "bonus"], o.bonusPoints);
> > }
> >
> > REDUCE
> >
> > _sum
> >
> > QUERY
> >
> > ?group=true&startkey=["gold"]&endkey=["gold",{}]
> >
> >
> > Regards,
> >
> > Aurélien
> >
> >
> >> Début du message réexpédié :
> >>
> >> De: David Park <da...@points.com>
> >> Objet: Rép : couchdb erlang reduce - aggregate object
> >> Date: 13 juin 2018 à 20:17:19 UTC+2
> >> À: user@couchdb.apache.org
> >> Répondre à: user@couchdb.apache.org
> >>
> >> ok. so here's my test
> >>
> >> 3 docs
> >>
> >> {"_id": "a", "label": "gold", "basePoints": 1000, "bonusPoints": 2000}
> >> {"_id": "b", "label": "gold", "basePoints": 10000, "bonusPoints": 20000}
> >> {"_id": "c", "label": "silver", "basePoints": 10000, "bonusPoints":
> 20000}
> >>
> >> Then I took your advice and wrote a javascript (not erlang) view
> >>
> >> function(o) {
> >>   emit(o.label, o.basePoints);
> >>   emit(o.label, o.bonusPoints);
> >> }
> >>
> >> then threw in a reduce of
> >>
> >> _sum
> >>
> >> then I queried my view with group = true where key = label
> >> And I get a response of
> >> {
> >> "rows":[
> >>   {"key":"gold","value":33000}
> >> ]
> >> }
> >>
> >> I desire that value to be split out by base and bonus points.
> >>
> >> David Park   Software Developer
>
>

Re: couchdb erlang reduce - aggregate object

Posted by Robert Samuel Newson <rn...@apache.org>.
the built-in reduce ("_sum") handles both arrays and objects, so you should be able to just do;

map:
function(doc) {
  emit(doc.label, {"base":doc.basePoints, "bonus":doc.bonusPoints});
}

reduce:
_sum

B.

> On 13 Jun 2018, at 20:40, Aurélien Bénel <au...@utt.fr> wrote:
> 
> Dear David,
> 
>> I desire that value to be split out by base and bonus points.
> 
> Then you’ll need an array as the key: a first member for the selection and a second one for the grouping.
> 
> 
> MAP :
> 
> function(o) {
>   emit( [o.label, "base"] , o.basePoints);
>   emit( [o.label, "bonus"], o.bonusPoints);
> }
> 
> REDUCE
> 
> _sum
> 
> QUERY
> 
> ?group=true&startkey=["gold"]&endkey=["gold",{}]
> 
> 
> Regards,
> 
> Aurélien 
> 
> 
>> Début du message réexpédié :
>> 
>> De: David Park <da...@points.com>
>> Objet: Rép : couchdb erlang reduce - aggregate object
>> Date: 13 juin 2018 à 20:17:19 UTC+2
>> À: user@couchdb.apache.org
>> Répondre à: user@couchdb.apache.org
>> 
>> ok. so here's my test
>> 
>> 3 docs
>> 
>> {"_id": "a", "label": "gold", "basePoints": 1000, "bonusPoints": 2000}
>> {"_id": "b", "label": "gold", "basePoints": 10000, "bonusPoints": 20000}
>> {"_id": "c", "label": "silver", "basePoints": 10000, "bonusPoints": 20000}
>> 
>> Then I took your advice and wrote a javascript (not erlang) view
>> 
>> function(o) {
>>   emit(o.label, o.basePoints);
>>   emit(o.label, o.bonusPoints);
>> }
>> 
>> then threw in a reduce of
>> 
>> _sum
>> 
>> then I queried my view with group = true where key = label
>> And I get a response of
>> {
>> "rows":[
>>   {"key":"gold","value":33000}
>> ]
>> }
>> 
>> I desire that value to be split out by base and bonus points.
>> 
>> David Park   Software Developer


Re: couchdb erlang reduce - aggregate object

Posted by Aurélien Bénel <au...@utt.fr>.
Dear David,

> I desire that value to be split out by base and bonus points.

Then you’ll need an array as the key: a first member for the selection and a second one for the grouping.


MAP :

function(o) {
   emit( [o.label, "base"] , o.basePoints);
   emit( [o.label, "bonus"], o.bonusPoints);
}

REDUCE

_sum

QUERY

?group=true&startkey=["gold"]&endkey=["gold",{}]


Regards,

Aurélien 


> Début du message réexpédié :
> 
> De: David Park <da...@points.com>
> Objet: Rép : couchdb erlang reduce - aggregate object
> Date: 13 juin 2018 à 20:17:19 UTC+2
> À: user@couchdb.apache.org
> Répondre à: user@couchdb.apache.org
> 
> ok. so here's my test
> 
> 3 docs
> 
> {"_id": "a", "label": "gold", "basePoints": 1000, "bonusPoints": 2000}
> {"_id": "b", "label": "gold", "basePoints": 10000, "bonusPoints": 20000}
> {"_id": "c", "label": "silver", "basePoints": 10000, "bonusPoints": 20000}
> 
> Then I took your advice and wrote a javascript (not erlang) view
> 
> function(o) {
>    emit(o.label, o.basePoints);
>    emit(o.label, o.bonusPoints);
> }
> 
> then threw in a reduce of
> 
> _sum
> 
> then I queried my view with group = true where key = label
> And I get a response of
> {
>  "rows":[
>    {"key":"gold","value":33000}
>  ]
> }
> 
> I desire that value to be split out by base and bonus points.
> 
> David Park   Software Developer

Re: couchdb erlang reduce - aggregate object

Posted by David Park <da...@points.com>.
ok. so here's my test

3 docs

{"_id": "a", "label": "gold", "basePoints": 1000, "bonusPoints": 2000}
{"_id": "b", "label": "gold", "basePoints": 10000, "bonusPoints": 20000}
{"_id": "c", "label": "silver", "basePoints": 10000, "bonusPoints": 20000}

Then I took your advice and wrote a javascript (not erlang) view

function(o) {
    emit(o.label, o.basePoints);
    emit(o.label, o.bonusPoints);
}

then threw in a reduce of

_sum

then I queried my view with group = true where key = label
And I get a response of
{
  "rows":[
    {"key":"gold","value":33000}
  ]
}

I desire that value to be split out by base and bonus points.

David Park   Software Developer

M 416*.*461*.*2649

*Points  *|  More together.

Connect with us: Points <http://l.points.com/69s8/> | Twitter
<http://l.points.com/uxlj/> | Blog <http://l.points.com/vu4y/> | LinkedIn
<http://l.points.com/rjs4/> | Careers <http://l.points.com/juqh/>

TSX: PTS <http://l.points.com/sgf7/>; NASDAQ: PCOM
<http://l.points.com/ko1o/>

111 Richmond St W., Suite 700, Toronto, ON, M5H 2G4, Canada

Connect with me: LinkedIn <https://www.linkedin.com/in/butterdave>



On Wed, Jun 13, 2018 at 2:00 PM Aurélien Bénel <au...@utt.fr>
wrote:

>
> > This will reduce both values into one, but I would like to keep these
>
> It won’t since keys are different and « group=true » is equivalent to «
> group_level=exact ».
> Please test it.
>
>
>
> Regards,
>
> Aurélien
>
>
>

Re: couchdb erlang reduce - aggregate object

Posted by Aurélien Bénel <au...@utt.fr>.
> This will reduce both values into one, but I would like to keep these

It won’t since keys are different and « group=true » is equivalent to « group_level=exact ».
Please test it.



Regards,

Aurélien



Re: couchdb erlang reduce - aggregate object

Posted by David Park <da...@points.com>.
This will reduce both values into one, but I would like to keep these
notions separate.



David Park   Software Developer

M 416*.*461*.*2649

*Points  *|  More together.

Connect with us: Points <http://l.points.com/69s8/> | Twitter
<http://l.points.com/uxlj/> | Blog <http://l.points.com/vu4y/> | LinkedIn
<http://l.points.com/rjs4/> | Careers <http://l.points.com/juqh/>

TSX: PTS <http://l.points.com/sgf7/>; NASDAQ: PCOM
<http://l.points.com/ko1o/>

111 Richmond St W., Suite 700, Toronto, ON, M5H 2G4, Canada

Connect with me: LinkedIn <https://www.linkedin.com/in/butterdave>



On Wed, Jun 13, 2018 at 1:33 PM Aurélien Bénel <au...@utt.fr>
wrote:

> Hi David,
>
> You’ll need a map function:
>
>     function(o) {
>       emit(‘basePoints’, o.basePoints);
>       emit(‘bonusPoints’, o.bonusPoints);
>     }
>
> A reduce function:
>
>     _sum
>
> And you’ll have to call your view with:
>
>     ?group=true
>
>
> Regards,
>
> Aurélien
>
> > Le 13 juin 2018 à 19:13, David Park <da...@points.com> a écrit :
> >
> > Say I have a map that emits the following object:
> >
> >>>> {"basePoints": 2000, "bonusPoints": 1000}
> >>>> {"basePoints": 1000, "bonusPoints": 50}
> >>>> {"basePoints": 10000, "bonusPoints": 5000}
> >
> > How could I write a reduce in Erlang that would return an aggregate
> object
> > like this:
> >
> >>>> {"basePoints": 13000, "bonusPoints": 6050}
> >
> > (I would rather not have to write 2 separate views that emit each value
> > separately if i can help it)
> >
> > Thanks!
> >
> > David Park   Software Developer
>
>

Re: couchdb erlang reduce - aggregate object

Posted by Aurélien Bénel <au...@utt.fr>.
Hi David,

You’ll need a map function:

    function(o) {
      emit(‘basePoints’, o.basePoints);
      emit(‘bonusPoints’, o.bonusPoints);
    }

A reduce function: 

    _sum

And you’ll have to call your view with:

    ?group=true


Regards,

Aurélien

> Le 13 juin 2018 à 19:13, David Park <da...@points.com> a écrit :
> 
> Say I have a map that emits the following object:
> 
>>>> {"basePoints": 2000, "bonusPoints": 1000}
>>>> {"basePoints": 1000, "bonusPoints": 50}
>>>> {"basePoints": 10000, "bonusPoints": 5000}
> 
> How could I write a reduce in Erlang that would return an aggregate object
> like this:
> 
>>>> {"basePoints": 13000, "bonusPoints": 6050}
> 
> (I would rather not have to write 2 separate views that emit each value
> separately if i can help it)
> 
> Thanks!
> 
> David Park   Software Developer