Return-Path: Delivered-To: apmail-incubator-couchdb-dev-archive@locus.apache.org Received: (qmail 40792 invoked from network); 23 Jul 2008 12:59:07 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 23 Jul 2008 12:59:07 -0000 Received: (qmail 11443 invoked by uid 500); 23 Jul 2008 12:59:07 -0000 Delivered-To: apmail-incubator-couchdb-dev-archive@incubator.apache.org Received: (qmail 11406 invoked by uid 500); 23 Jul 2008 12:59:06 -0000 Mailing-List: contact couchdb-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: couchdb-dev@incubator.apache.org Delivered-To: mailing list couchdb-dev@incubator.apache.org Received: (qmail 11395 invoked by uid 99); 23 Jul 2008 12:59:06 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 23 Jul 2008 05:59:06 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of matt.goodall@gmail.com designates 66.249.92.175 as permitted sender) Received: from [66.249.92.175] (HELO ug-out-1314.google.com) (66.249.92.175) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 23 Jul 2008 12:58:12 +0000 Received: by ug-out-1314.google.com with SMTP id m3so514445ugc.15 for ; Wed, 23 Jul 2008 05:58:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:in-reply-to:mime-version:content-type :content-transfer-encoding:content-disposition:references; bh=W0Cqd1ClcexqSvbGu5iPjAgBR7Ko5hzMSijioGMWZLM=; b=DvyzRC/3/+jyKYn4a8loeKrn3/C0COmn+p/0WBD5jWZG3PkZqRvPLx3IHD1KgqH8cP Yc3xARncl0d+zbLmscmblPmWA27uYXowYL7TEsSyAGxuUIs1MHaj+ma5comvGj9wlzVx BxltQinahkfMh0q0nEPb+MntQkB6gBDXdZqJI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references; b=m1iYu/VgdvlUyNeJ1peqzbEZ4sv5HMlYKfBwN//16MYLU0ON8pNw7lYOwQJcLSyaib yYkgcLrD1q8P2bBJGV5J9lQj1jgrsA4wLkAUCg4Zo9iWhbsaIfv3JCRyx2hYOSehlxfm JfLz162Srz72NN98ZCQKakw46Kavc63xvFXr8= Received: by 10.67.22.2 with SMTP id z2mr257465ugi.34.1216817916724; Wed, 23 Jul 2008 05:58:36 -0700 (PDT) Received: by 10.66.249.14 with HTTP; Wed, 23 Jul 2008 05:58:36 -0700 (PDT) Message-ID: <214c385b0807230558ga728ea0xfd98facd333f543e@mail.gmail.com> Date: Wed, 23 Jul 2008 13:58:36 +0100 From: "Matt Goodall" To: couchdb-dev@incubator.apache.org Subject: Re: [PATCH] Views: Multiple keys In-Reply-To: <20080723053624.GA8963@pib-laptop> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <20080723053624.GA8963@pib-laptop> X-Virus-Checked: Checked by ClamAV on apache.org 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 : > 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 > -- > > 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"}); > >