I corrected an error and I also had to split into two views (descendants and
metrics) because I hit the reduce-size-restriction. This means that I have
to hit CouchDB two times for each node but I do not care because the
requests and responses are relatively small. The views work now correctly
and pretty faaaaaast on about 5000 documents. I am still interested on
feedback on how to improve the views (looks like I am going to continue
using CouchDB).
Here are my results (I had to reformat them a little for better readability
-> see below). Does anybody know a good linux editor that works with CouchDB
design documents. I am already sick of cut/paste them from/to Futon.
{
"_id": "_design/tree",
"_rev": "4-305fc8f8e6c6b52f9656a5c8c0b0164e",
"language": "javascript",
"views": {
"metrics": {
"map": "function(doc) {\u000a if(doc[\"File\"] !==
undefined) {\u000a // emit root\u000a emit(\"*\", doc);\u000a
var pathelements = doc[\"File\"].split(\"/\");\u000a var path =
\"\";\u000a // emit all subpath\u000a for (elem in pathelements)
{\u000a path += pathelements[elem];\u000a if (elem <
pathelements.length-1) {\u000a path += \"/\";\u000a
}\u000a\u0009emit(path, doc);\u000a }\u000a }\u000a}",
"reduce": "function(keys, values, rereduce){\u000a //
helper function to check whether an element is contained in an
array\u000a contains = function (array, element) {\u000a for
(elem in array) {\u000a if (array[elem] == element) {\u000a
return true;\u000a }\u000a }\u000a
return false;\u000a };\u000a\u000a var output = {\u000a
\"CountLineCode\": 0,\u000a \"SumCyclomatic\": 0\u000a
};\u000a\u000a if (!rereduce) {\u000a for(idx in values)
{\u000a if (values[idx].CountLineCode !== undefined)
{\u000a output.CountLineCode +=
values[idx].CountLineCode;\u000a }\u000a if
(values[idx].SumCyclomatic !== undefined) {\u000a
output.SumCyclomatic += values[idx].SumCyclomatic;\u000a
}\u000a }\u000a } \u000a else { // rereduce\u000a
for (idx in values) {\u000a output.CountLineCode +=
values[idx].CountLineCode;\u000a output.SumCyclomatic +=
values[idx].SumCyclomatic;\u000a }\u000a }\u000a return
output;\u000a}"
},
"descendants": {
"map": "function(doc) {\u000a if(doc[\"File\"] !==
undefined) {\u000a var pathelements =
doc[\"File\"].split(\"/\");\u000a var path = \"*\"; // used as root
of the tree\u000a for (var idx = 0; idx < pathelements.length;
idx++) {\u000a next = pathelements[idx];\u000a if (idx <
pathelements.length-1) {\u000a next += \"/\";\u000a
}\u000a emit(path, next);\u000a if (path === \"*\")
{\u000a path = next;\u000a } else {\u000a
path = path + next;\u000a }\u000a }\u000a }\u000a}"
}
}
}
reformated for better readability:
{
"_id": "_design/node",
"_rev": "5-7aa152a0ec388039acf1c2e975c3c1c1",
"language": "javascript",
"views": {
"metrics": {
"map": "function(doc) {
if(doc["File"] !== undefined) {
// emit root
emit("*", doc);
var pathelements = doc["File"].split("/");
var path = "";
// emit all subpath
for (elem in pathelements) {
path += pathelements[elem];
if (elem < pathelements.length-1) {
path += "/";
}
emit(path, doc);
}
}
}",
"reduce": "function(keys, values, rereduce){
// helper function to check whether an element is contained in an array
contains = function (array, element) {
for (elem in array) {
if (array[elem] == element) {
return true;
}
}
return false;
};
var output = {
"CountLineCode": 0,
"SumCyclomatic": 0
};
if (!rereduce) {
for(idx in values) {
if (values[idx].CountLineCode !== undefined) {
output.CountLineCode += values[idx].CountLineCode;
}
if (values[idx].SumCyclomatic !== undefined) {
output.SumCyclomatic += values[idx].SumCyclomatic;
}
}
}
else { // rereduce
for (idx in values) {
output.CountLineCode += values[idx].CountLineCode;
output.SumCyclomatic += values[idx].SumCyclomatic;
}
}
return output;
}"
},
"descendants": {
"map": "function(doc) {
if(doc["File"] !== undefined) {
var pathelements = doc["File"].split("/");
var path = "*"; // used as root of the tree
for (var idx = 0; idx < pathelements.length; idx++) {
next = pathelements[idx];
if (idx < pathelements.length-1) {
next += "/";
}
emit(path, next);
if (path === "*") {
path = next;
} else {
path = path + next;
}
}
}
}"
}
}
}