franssois
franssois

Reputation: 57

How to return an JSON object I made in a reduce function

I need your help about CouchDB reduce function. I have some docs like:

{'about':'1', 'foo':'a1','bar':'qwe'}
{'about':'1', 'foo':'a1','bar':'rty'}
{'about':'1', 'foo':'a2','bar':'uio'}
{'about':'1', 'foo':'a1','bar':'iop'}
{'about':'2', 'foo':'b1','bar':'qsd'}
{'about':'2', 'foo':'b1','bar':'fgh'}
{'about':'3', 'foo':'c1','bar':'wxc'}
{'about':'3', 'foo':'c2','bar':'vbn'}

As you can seen they all have the same key, just the values are differents. My purpse is to use a Map/Reduce and my return expectation would be:

'rows':[ 'keys':'1','value':{'1':{'foo':'a1', 'at':'rty'},
                             '2':{'foo':'a2', 'at':'uio'},
                             '3':{'foo':'a1', 'at':'iop'}}
         'keys':'1','value':{'foo':'a1', 'bar','rty'}
          ...
         'keys':'3','value':{'foo':'c2', 'bar',vbn'}
       ]

Here is the result of my Map function:

'rows':[ 'keys':'1','value':{'foo':'a1', 'bar','qwe'}
         'keys':'1','value':{'foo':'a1', 'bar','rty'}
          ...
         'keys':'3','value':{'foo':'c2', 'bar',vbn'}
       ]

But my Reduce function isn't working:

function(keys,values,rereduce){
  var res= {};
  var lastCheck = values[0];
  for(i=0; i<values.length;++i)
  {
    value = values[i];
    if (lastCheck.foo != value.foo)
    {
      res.append({'change':[i:lastCheck]});
    }
    lastCheck = value;
   }
   return res;
 }

Is it possible to have what I expect or I need to use an other way ?

Upvotes: 2

Views: 1198

Answers (2)

zlr
zlr

Reputation: 829

Apparently now you need to use

provides('json', function() { ... }); 

As in: Simplify Couchdb JSON response

Upvotes: 0

Akshat Jiwan Sharma
Akshat Jiwan Sharma

Reputation: 16050

You should not do this in the reduce function. As the couchdb wiki explains:-

If you are building a composite return structure in your reduce, or only transforming the values field, rather than summarizing it, you might be misusing this feature.

There are two approaches that you can take instead

  1. Transform the results at your application layer.

  2. Use the list function.

Lists functions are simple. I will try to explain them here:

Lists like views are saved in design documents under the key lists. Like so:

"lists":{

  "formatResults" : "function(head,req) {....}" 

}

To call the list function you use a url like this

http://localhost:5984/your-database/_design/your-designdoc/_list/your-list-function/your-view-name

Here is an example of list function

function(head, req) {
  var row = getRow();
  if (!row){
    return 'no ingredients'
   }

  var jsonOb = {};

  while(row=getRow()){
     //construct the json object here
  }
     return {"body":jsonOb,"headers":{"Content-Type" : "application/json"}};
}

The getRow function is of interest to us. It contains the result of the view. So we can query it like

row.key for key

row.value for value

All you have to do now is construct the json like you want and then send it.

By the way you can use log to debug your functions.

I hope this helps a little.

Upvotes: 3

Related Questions