Я предпочитаю уменьшать / уменьшать неявно, а не в зависимости от параметра rereduce
.
function(doc) { // map
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], {id:doc._id, tag:doc.tags[t]});
}
}
}
Затем уменьшать проверяет, накапливает ли он идентификаторы документов из идентичного тега или он просто считает разные теги.
function(keys, vals, rereduce) {
var initial_tag = vals[0].tag;
return vals.reduce(function(state, val) {
if(initial_tag && val.tag === initial_tag) {
// Accumulate ids which produced this tag.
var ids = state.ids;
if(!ids)
ids = [ state.id ]; // Build initial list from the state's id.
return { tag: val.tag,
, ids: ids.concat([val.id])
};
} else {
var state_count = state.ids ? state.ids.length : state;
var val_count = val.ids ? val.ids.length : val;
return state_count + val_count;
}
})
}
(Я не тестировал этот код, но вы поняли. Пока значение tag
одинаково, оно не имеет значения, является ли это уменьшением или редукцией. Как только различные теги начинают сокращаться вместе, он обнаруживает это, потому что значение tag
изменится. Так что в этот момент просто начинайте накапливаться.
Я использовалэтот трюк раньше, хотя IMO редко стоит.
Также в в вашем конкретном случае , это опасная функция сокращения. Вы строите широкий список, чтобы увидеть все документы, которые имеюттег. CouchDB любит высокие списки, а не толстые списки. Если вы хотите увидеть все документы, которые имеют тег, вы можете отобразить их.
for(var a = 0; a < doc.tags.length; a++) {
emit(doc.tags[a], doc._id);
}
Теперь вы можете запросить /db/_design/app/_view/docs_by_tag?key="3d"
, и вы должны получить
{"total_rows":287,"offset":30,"rows":[
{"id":"project1","key":"3d","value":"project1"}
{"id":"project3","key":"3d","value":"project3"}
{"id":"project8","key":"3d","value":"project8"}
{"id":"project10","key":"3d","value":"project10"}
]}