Router reports not_found error for a view

26 views
Skip to first unread message

Eno

unread,
Feb 23, 2015, 5:34:08 PM2/23/15
to mobile-c...@googlegroups.com
The design doc in this database, from http://localhost:5984/database/_design/fabric is:

"doc": {
                "language": "javascript",
                "version": 1,
                "views": {
                    "seen": {
                        "map": "function(doc) { if (doc.threadId && doc.comments) { emit(doc.threadId.toLowerCase(), doc.comments); } }",
                        "reduce": "_sum"
                    }
                },
                "_rev": "1-682802a943cdabb7a6e51f1757f1d18b",
                "_id": "_design/fabric"
            },
            "id": "_design/fabric",
            "key": "_design/fabric",
            "value": {
                "_conflicts": [],
                "rev": "1-682802a943cdabb7a6e51f1757f1d18b"
            }

So Im trying to call http://localhost:5984/database/_design/fabric/_view/seen and get the error:

{
    "error": "not_found",
    "reason": "Router unable to route request to do_GET_DesignDocumentjava.lang.reflect.InvocationTargetException"
}


What am I doing wrong?

Eno

unread,
Feb 23, 2015, 5:58:15 PM2/23/15
to mobile-c...@googlegroups.com
OK, looks like there is no _sum() builtin. Anyone care to share an example sum function? :-)

Jens Alfke

unread,
Feb 23, 2015, 8:01:21 PM2/23/15
to mobile-c...@googlegroups.com

On Feb 23, 2015, at 2:58 PM, Eno <sym...@gmail.com> wrote:

OK, looks like there is no _sum() builtin. Anyone care to share an example sum function? :-)

It’s a good learning exercise to write one. It’s very simple, and if you’re working with reduce you should know how to write a reduce function :)

—Jens

Eno

unread,
Feb 23, 2015, 8:45:45 PM2/23/15
to mobile-c...@googlegroups.com
Im only asking AFTER I tried several different ways...

Jens Alfke

unread,
Feb 24, 2015, 11:52:30 AM2/24/15
to mobile-c...@googlegroups.com
function(keys, values, rereduce) {
var total = 0;
for (var i=0; i<values.length; i++)
total += values[i];
return total;
}

—Jens

Eno

unread,
Feb 24, 2015, 12:24:33 PM2/24/15
to mobile-c...@googlegroups.com
The reduce function Im using is:
function(key, values) { var s = 0; for(i = 0; i < values.length; i++) { s += values[i]; } return s; }

But the combined map-reduce doesn't produce what I want which is totals for each thread.
The data Im working with is simple: documents containing a threadId and a counter, e.g.

{
    threadId: "78d7bb17-7c89-456f-82e8-e18f1727c1f7",
    comments: 1
}


The complete design doc for my view looks like this:
{
    "total_rows": 1,
    "offset": 0,
    "rows": [
        {
            "doc": {
                "language": "javascript",
                "version": 1,
                "views": {
                    "seen": {
                        "map": "function(doc) { if (doc.threadId && doc.comments) { emit(doc.threadId.toLowerCase(), doc.comments); } }",
                        "reduce": "function(key, values) { var s = 0; for(i = 0; i < values.length; i++) { s += values[i]; } return s; }"
                    }
                },
                "_rev": "1-a75768a5fc3b5cc2304adc7d5bfb37f6",
                "_id": "_design/fabric"
            },
            "id": "_design/fabric",
            "key": "_design/fabric",
            "value": {
                "_conflicts": [],
                "rev": "1-a75768a5fc3b5cc2304adc7d5bfb37f6"
            }
        }
    ]
}

My understanding is that reduce only happens when group=true is supplied via query string right?

The output Im getting shows the total for all documents and only one threadId even though my sample data is four documents conmtaining two unique threads with totals.

For sure, Im misunderstanding :-)

Jens Alfke

unread,
Feb 24, 2015, 3:52:38 PM2/24/15
to mobile-c...@googlegroups.com
On Feb 24, 2015, at 9:24 AM, Eno <sym...@gmail.com> wrote:

My understanding is that reduce only happens when group=true is supplied via query string right?

If the view has a reduce function defined, queries will reduce by default unless you add ?reduce=false.

You need to use ?group_level=1. (The boolean ?group query isn’t needed; as far as I know, it’s an unnecessary evolutionary relic from old versions of CouchDB.)

The best documentation of the REST API for queries is CouchDB’s. (I apologize for our comparable docs being, um, somewhat less comprehensive. Fortunately the API is basically the same.) But we do have good documentation on the principles of querying, including grouping.

—Jens

Eno

unread,
Feb 24, 2015, 4:15:03 PM2/24/15
to mobile-c...@googlegroups.com
FYI Im using Couchbase-Lite and yeah the documentation could do with some love :-)

I tried group_level:

Output:
{
    "total_rows": 1,
    "offset": 0,
    "rows": [
        {
            "id": null,
            "key": "ryan",
            "value": 1
        }
    ]
}

The key "ryan" is one of the threadIds but there are actually two threadId's and 8 documents in total.
The value of "value" appears to be the correct total for all ryan's threads.

Also dont know if I need to worry about rereduce?

Jens Alfke

unread,
Feb 24, 2015, 5:05:46 PM2/24/15
to mobile-c...@googlegroups.com
On Feb 24, 2015, at 1:15 PM, Eno <sym...@gmail.com> wrote:

The key "ryan" is one of the threadIds but there are actually two threadId's and 8 documents in total.
The value of "value" appears to be the correct total for all ryan's threads.

Hm, weird. Try querying the view with ?reduce=false to see what all of the rows in the view are. It may be that for some reason the other rows didn’t get emitted.

Also dont know if I need to worry about rereduce?

The ‘total’ function happens to be one that will work fine with rereduce with no extra work. (Totaling up a bunch of totals produces the right answer, thanks to the associative property of addition.) But yes, many reduce functions do have to behave differently when the ‘rereduce' flag is set.

—Jens

Eno

unread,
Feb 24, 2015, 5:58:04 PM2/24/15
to mobile-c...@googlegroups.com
Ah yes, I see now that not all the rows are being emitted. Will remove conditional and re-test.

Eno

unread,
Feb 24, 2015, 6:08:02 PM2/24/15
to mobile-c...@googlegroups.com
OK time to slap my head a few times :-)

I think when doc.comments is 0 then if (doc.threadId && doc.comments) == false and then those rows fail to be emitted :-)
Changing my map to if (doc.threadId) { emit(doc.threadId, doc.comments) } seems to work.

Many thanks for your help.
Reply all
Reply to author
Forward
0 new messages