You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2023/04/10 22:09:31 UTC

[couchdb] 01/01: tighten sort field type check and enhance docs

This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch import-nouveau
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit bcb9f80edde0c0012746d5e5b4b07f046131decb
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon Apr 10 22:45:21 2023 +0100

    tighten sort field type check and enhance docs
---
 .../apache/couchdb/nouveau/lucene9/Lucene9Index.java  | 19 +++++++++++++++----
 src/docs/src/api/ddoc/nouveau.rst                     | 15 +++++++--------
 src/nouveau/src/nouveau_httpd.erl                     |  2 ++
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene9/Lucene9Index.java b/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene9/Lucene9Index.java
index 64b55aa5c..27105d6b9 100644
--- a/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene9/Lucene9Index.java
+++ b/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene9/Lucene9Index.java
@@ -79,7 +79,7 @@ public class Lucene9Index extends Index {
 
     private static final Sort DEFAULT_SORT = new Sort(SortField.FIELD_SCORE,
             new SortField("_id", SortField.Type.STRING));
-    private static final Pattern SORT_FIELD_RE = Pattern.compile("^([-+])?([\\.\\w]+)(?:<(\\w+)>)?$");
+    private static final Pattern SORT_FIELD_RE = Pattern.compile("^([-+])?([\\.\\w]+)(?:<(\\w+)>)$");
 
     private final Analyzer analyzer;
     private final IndexWriter writer;
@@ -329,15 +329,26 @@ public class Lucene9Index extends Index {
     }
 
     private SortField convertSortField(final String sortString) {
+        if ("relevance".equals(sortString)) {
+            return SortField.FIELD_SCORE;
+        }
         final Matcher m = SORT_FIELD_RE.matcher(sortString);
         if (!m.matches()) {
             throw new WebApplicationException(
                     sortString + " is not a valid sort parameter", Status.BAD_REQUEST);
         }
         final boolean reverse = "-".equals(m.group(1));
-        SortField.Type type = SortField.Type.DOUBLE;
-        if ("string".equals(m.group(3))) {
-            type = SortField.Type.STRING;
+        SortField.Type type;
+        switch (m.group(3)) {
+            case "string":
+                type = SortField.Type.STRING;
+                break;
+            case "number":
+                type = SortField.Type.DOUBLE;
+                break;
+            default:
+                throw new WebApplicationException(
+                        m.group(3) + " is not a valid sort type", Status.BAD_REQUEST);
         }
         return new SortField(m.group(2), type, reverse);
     }
diff --git a/src/docs/src/api/ddoc/nouveau.rst b/src/docs/src/api/ddoc/nouveau.rst
index e387bd1f8..d38d16e43 100644
--- a/src/docs/src/api/ddoc/nouveau.rst
+++ b/src/docs/src/api/ddoc/nouveau.rst
@@ -58,16 +58,15 @@
         and optional ``min_inclusive`` and ``max_inclusive`` properties (defaulting to
         ``true`` if not specified).
         Example: ``{"bar":[{"label":"cheap","min":0,"max":100}]}``
-    :query json sort: Specifies the sort order of the results. In a grouped search (when
-        ``group_field`` is used), this parameter specifies the sort order within a group.
+    :query json sort: Specifies the sort order of the results.
         The default sort order is relevance. A JSON string of the form
         ``"fieldname<type>"`` or ``"-fieldname<type>"`` for descending order, where
-        fieldname is the name of a string or number field, and ``type`` is either a
-        number, a string, or a JSON array of strings. The ``type`` part is optional, and
-        defaults to number. Some examples are ``"foo"``, ``"-foo"``, ``"bar<string>"``,
-        ``"-foo<number>"`` and [``"-foo<number>"``, ``"bar<string>"``]. String fields that
-        are used for sorting must not be analyzed fields. Fields that are used for sorting
-        must be indexed by the same indexer that is used for the search query.
+        fieldname is the name of a string or number field, and ``type`` is either
+        ``number`` or ``string``. You can use a single string to sort by one field
+        or an array of strings to sort by several fields in the same order as the
+        array.
+        Some examples are ``"relevance"``, ``"bar<string>"``,
+        ``"-foo<number>"`` and [``"-foo<number>"``, ``"bar<string>"``].
     :query boolean update: Set to ``false`` to allow the use of an out-of-date index.
 
     :>header Content-Type: - :mimetype:`application/json`
diff --git a/src/nouveau/src/nouveau_httpd.erl b/src/nouveau/src/nouveau_httpd.erl
index c60988c25..0fe80c5d9 100644
--- a/src/nouveau/src/nouveau_httpd.erl
+++ b/src/nouveau/src/nouveau_httpd.erl
@@ -186,6 +186,8 @@ validate_query_arg(limit, List) when is_list(List) ->
     end;
 validate_query_arg(sort, undefined) ->
     null;
+validate_query_arg(sort, {json, Sort}) when is_binary(Sort) ->
+    [Sort];
 validate_query_arg(sort, {json, Sort}) ->
     ok = is_list_of_strings(<<"counts">>, Sort),
     Sort;