سؤال

Ok, I've been banging my head for a way around this all weekend, and I'm finally stumped. My reduce map func:

function(doc) {
 if(doc.primary_keys) {
    for(pi in doc.primary_keys) {
        var pk = doc.primary_keys[pi];

        for(row_i in doc.data) {
            var row = doc.data[row_i];
            if(row[pk]) {
                emit([row[pk]], doc._id);
            }
        }
    }
 }
}

And my view reduce:

 function(keys, values) {
   var retval = {};

   for(var val_i in values) {
       var key = values[val_i];

       if(key in retval) {
           retval[key] += 1;
       } else {
           retval[key] = 1;
       }
    }

    return(retval);
 }

This is what my local (Couchbase) CouchDB returns:

key      value
["a"]    {test2: 1, test: 1}

But here's Cloudant returns:

key      value
["a"]        {[object Object]: 1, [object Object]: 1}

I've suspected some js env difference, but every workaround solution leads me to the same issus; Cloudant's value for values[val_i] is Object type, where I'd expect a string. I have no idea why. I'm pretty open to re-reduce at this point if it helps.

Why exactly are these different???

هل كانت مفيدة؟

المحلول

First up you need to specify how your reduce function works in a rereduce case (http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views has info). On Cloudant the rereduce is always called (to collect data from the various shards into the final view result). That's why you get the response you see.

Second, it looks like you're trying to get a count of data by primary_key. In general you want to use the built in _sum function for that - it's faster than custom js code, and _sum works over objects in Cloudant.

Third, the unreduced view will contain the doc._id automatically, so emit a 1 instead to make the _sum work.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top