|
Re: [PATCH] Views: Multiple keys: msg#00105db.couchdb.devel
Hi, I think this functionality would be hugely beneficial in CouchDB but POST'ing to a view seems so very, very wrong to me. How about using a GET on the view but support multiple 'key' args, one for each of the view rows to return, e.g. GET /somedb/_views/somedoc/someview?key=1&key=2&key=3 The 'key' arg(s) already seem to take precedence over startkey, endkey, etc and the view always returns a 'rows' list so it /should/ be a matter of iterating the JSON values sent as 'key' instead of parsing the JSON structure sent as POST content. I guess there's the possibility of hitting max URL length problems on some browsers/servers but that can be worked around by requesting the view in batches of keys. Thoughts? - Matt 2008/7/23 Paul Bonser <misterpib-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>: > After exploring the source code a bit and abandoning a few other ways of > achieving this, I've managed to get multi-key requests working. The only way > to make it more efficient would require some digging into the couch_btree > folding code, I think. > > You use it by POSTing a JSON array of keys to a view url. Any passed-in > values for start_key and end_key are ignored. > > I haven't written any unittests for this yet, but I wanted to see what > everyone else thinks of this and ask if there's any obvious better way to > accomplish the same goal. > > This patch is against the latest in SVN as of now. Any comments or > suggestions for this are very much welcome. > > > Signed-off-by: Paul Bonser <misterpib-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx> > -- > > diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl > index af8d9b4..c813a4c 100644 > --- a/src/couchdb/couch_httpd.erl > +++ b/src/couchdb/couch_httpd.erl > @@ -363,6 +363,37 @@ handle_db_request(Req, 'GET', {DbName, _Db, ["_view", > DocId, ViewName]}) -> > end > end; > > +% Multi-key request, with a JSON array of keys as the POST body > +handle_db_request(Req, 'POST', {DbName, _Db, ["_view", DocId, ViewName]}) -> > + #view_query_args{ > + count = Count, > + skip = SkipCount, > + direction = Dir, > + start_docid = StartDocId > + } = QueryArgs = parse_view_query(Req), > + > + case Req:get_primary_header_value("content-type") of > + undefined -> ok; > + "application/json" -> ok; > + Else -> throw({incorrect_mime_type, Else}) > + end, > + JsonKeys = tuple_to_list(cjson:decode(Req:recv_body())), > + > + {ok, View} = couch_view:get_map_view({DbName, "_design/" ++ DocId, > ViewName}), > + {ok, RowCount} = couch_view:get_row_count(View), > + FoldAccInit = {Count, SkipCount, undefined, []}, > + FoldResult = lists:foldl(fun(Key, {ok, FoldAcc}) -> > + Start = {Key, StartDocId}, > + FoldlFun = make_view_fold_fun(Req, QueryArgs#view_query_args { > + start_key = Key, > + end_key = Key > + }, > + RowCount, fun couch_view:reduce_to_count/1), > + couch_view:fold(View, Start, Dir, FoldlFun, FoldAcc) > + end, {ok, FoldAccInit}, JsonKeys), > + finish_view_fold(Req, RowCount, FoldResult); > + > + > handle_db_request(_Req, _Method, {_DbName, _Db, ["_view", _DocId, > _ViewName]}) -> > throw({method_not_allowed, "GET,HEAD"}); > > |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | [PATCH] Views: Multiple keys: 00105, Paul Bonser |
|---|---|
| Next by Date: | Re: [PATCH] Views: Multiple keys: 00105, Paul Bonser |
| Previous by Thread: | [PATCH] Views: Multiple keysi: 00105, Paul Bonser |
| Next by Thread: | Re: [PATCH] Views: Multiple keys: 00105, Paul Bonser |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |