Reduce output must shrink more rapidly — Reducing to a list of documents

自古美人都是妖i 提交于 2019-12-12 02:35:53

问题


I have a few documents in my couch db with json as below. The cId will change for each. And I have created a view with map/reduce function to filter out few documents and return a list of json documents.

Document structure -

{
  "_id": "ccf8a36e55913b7cf5b015d6c50009f7",
  "_rev": "8-586130996ad60ccef54775c51599e73f",
  "cId": 1,
  "Status": true
}

Here is the sample map:

function(doc) {
  if(doc.Key && doc.Value && doc.Status == true)
      emit(null, doc);
}

Here is the sample reduce:

function(key, values, rereduce){

var kv = [];

values.forEach(function(value){
   if(value.cId != <some_val>){
       kv.push({"k": value.cId, "v" : value});  
   }
});          

return kv;
}

If there are two documents and reduce output has list containing 1 document, this works fine. But if I add one more document (with cId = 2), it throws the errors - "reduce output must shrink more rapidly". Why is this caused? And how can I achieve what I intend to do?


回答1:


The cause of the error is, that the reduce function does not actually reduce anything (it rather is collecting objects). The documentation mentions this:

The way the B-tree storage works means that if you don’t actually reduce your data in the reduce function, you end up having CouchDB copy huge amounts of data around that grow linearly, if not faster with the number of rows in your view.

CouchDB will be able to compute the final result, but only for views with a few rows. Anything larger will experience a ridiculously slow view build time. To help with that, CouchDB since version 0.10.0 will throw an error if your reduce function does not reduce its input values.

It is unclear to me, what you intend to achieve. Do you want to retrieve a list of docs based on certain criteria? In this case, a view without reduce should suffice.

Edit: If the desired result depends on a value stored in a certain document, then CouchDB has a feature called list. It is a design function, that provides access to all docs of a given view, if you pass include_docs=true.

A list URL follow this pattern:

/db/_design/foo/_list/list-name/view-name

Like views, lists are defined in a design document:

{
  "_id" : "_design/foo",
  "lists" : {
    "bar" : "function(head, req) { 
       var row;
       while (row = getRow()) {
         if (row.doc._id === 'baz') // Do stuff based on a certain doc
       } 
    }"
  },
  ... // views and other design functions
}


来源:https://stackoverflow.com/questions/39544175/reduce-output-must-shrink-more-rapidly-reducing-to-a-list-of-documents

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!