Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

avoid JSON object encoding problem by changing multiple query feature…

… syntax. closes #57.
  • Loading branch information...
commit caccea472707e229053594230507f03f7033bc6f 1 parent 645a17e
@rnewson authored
@@ -0,0 +1,3 @@
+Multiple queries must now be comma-separated (previously the document said "multiple q parameters"). This is due to a JSON encoding problem (a JSON object cannot have non-unique keys).
2 
@@ -376,7 +376,7 @@ The following parameters can be passed for more sophisticated searches;
<dt>force_json<dt><dd>Usually couchdb-lucene determines the Content-Type of its response based on the presence of the Accept header. If Accept contains "application/json", you get "application/json" in the response, otherwise you get "text/plain;charset=utf8". Some tools, like JSONView for FireFox, do not send the Accept header but do render "application/json" responses if received. Setting force_json=true forces all response to "application/json" regardless of the Accept header.</dd>
<dt>include_docs</dt><dd>whether to include the source docs</dd>
<dt>limit</dt><dd>the maximum number of results to return</dd>
-<dt>q</dt><dd>the query to run (e.g, subject:hello). If not specified, the default field is searched. Multiple q parameters are permitted, the resulting JSON will be an array of responses.</dd>
+<dt>q</dt><dd>the query to run (e.g, subject:hello). If not specified, the default field is searched. Multiple queries can be supplied, separated by commas; the resulting JSON will be an array of responses.</dd>
<dt>skip</dt><dd>the number of results to skip</dd>
<dt>sort</dt><dd>the comma-separated fields to sort on. Prefix with / for ascending order and \ for descending order (ascending is the default if not specified). Type-specific sorting is also available by appending the type between angle brackets (e.g, sort=amount<float>). Supported types are 'float', 'double', 'int', 'long' and 'date'.</dd>
<dt>stale=ok</dt><dd>If you set the <i>stale</i> option to <i>ok</i>, couchdb-lucene may not perform any refreshing on the index. Searches may be faster as Lucene caches important data (especially for sorting). A query without stale=ok will use the latest data committed to the index.</dd>
@@ -5,7 +5,6 @@
import sys
import traceback
import urllib
-import re
import json
@@ -16,9 +15,6 @@
httpdict = {"etag":"ETag", "content-type":"Content-Type"}
-query_re = re.compile('(?:"query":{)([^}]+)')
-arg_re = re.compile('("\w+"):("[^"]+")')
def options():
return [
op.make_option('--remote-host', dest='remote_host',
@@ -38,11 +34,10 @@ def main():
if len(args):
parser.error("Unrecognized arguments: %s" % ' '.join(args))
- for line in requests():
- req = json.loads(line)
+ for req in requests():
res = httplib.HTTPConnection(opts.remote_host, opts.remote_port)
- resp = respond(res, req, line, opts.key)
+ resp = respond(res, req, opts.key)
except Exception, e:
body = traceback.format_exc()
resp = mkresp(500, body, {"Content-Type": "text/plain"})
@@ -55,10 +50,10 @@ def main():
def requests():
line = sys.stdin.readline()
while line:
- yield line
+ yield json.loads(line)
line = sys.stdin.readline()
-def respond(res, req, line, key):
+def respond(res, req, key):
path = req.get("path", [])
# Drop name of external hook.
@@ -69,19 +64,8 @@ def respond(res, req, line, key):
path[index] = urllib.quote(path[index], "")
path = '/'.join(['', key] + path)
- # Use regexps to extract query arguments so we can tolerate duplicate keys.
- query =
- if query is not None:
- # Make 2-tuples
- args = arg_re.findall(
- # unquote tuples
- args = [(k.strip('"'), json.loads(v)) for (k, v) in args]
- # urlencode the arguments
- params = urllib.urlencode(args)
- path = '?'.join([path, params])
+ params = urllib.urlencode(dict([k, v.encode('utf-8')] for k, v in req["query"].items()))
+ path = '?'.join([path, params])
req_headers = {}
for h in req.get("headers", []):
6 src/main/java/com/github/rnewson/couchdb/lucene/
@@ -449,7 +449,7 @@ public void search(final HttpServletRequest req,
- for (final String queryString : req.getParameterValues("q")) {
+ for (final String queryString : getQueryStrings(req)) {
final Query q = state.parser.parse(queryString);
final JSONObject queryRow = new JSONObject();
queryRow.put("q", q.toString());
@@ -606,6 +606,10 @@ public void search(final HttpServletRequest req,
+ private String[] getQueryStrings(final HttpServletRequest req) {
+ return req.getParameter("q").split(",");
+ }
private void close() throws IOException {
this.closed = true;
Please sign in to comment.
Something went wrong with that request. Please try again.