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 2026/07/28 12:31:23 UTC
(couchdb) branch nouveau-6075-sort-by-relevance created (now bb44851b6)
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a change to branch nouveau-6075-sort-by-relevance
in repository https://gitbox.apache.org/repos/asf/couchdb.git
at bb44851b6 Fix explicit sorting by relevance/score
This branch includes the following new commits:
new bb44851b6 Fix explicit sorting by relevance/score
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(couchdb) 01/01: Fix explicit sorting by relevance/score
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch nouveau-6075-sort-by-relevance
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit bb44851b6da0d664568f151e4fad1a7fb58a723c
Author: Robert Newson <rn...@apache.org>
AuthorDate: Tue Jul 28 13:30:18 2026 +0100
Fix explicit sorting by relevance/score
Also fixed some misleading docs (from the original import from previous search docs)
Closes https://github.com/apache/couchdb/issues/6075
---
.../apache/couchdb/nouveau/lucene/LuceneIndex.java | 6 +++-
src/docs/src/api/ddoc/nouveau.rst | 2 +-
test/elixir/test/config/nouveau.elixir | 4 ++-
test/elixir/test/nouveau_test.exs | 34 +++++++++++++++++++++-
4 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene/LuceneIndex.java b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene/LuceneIndex.java
index 14cc672e9..1384e75e7 100644
--- a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene/LuceneIndex.java
+++ b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/lucene/LuceneIndex.java
@@ -102,6 +102,7 @@ public class LuceneIndex 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]+)$");
+ private static final SortField FIELD_REVERSE_SCORE = new SortField(null, SortField.Type.SCORE, true);
private final Analyzer analyzer;
private final IndexWriter writer;
@@ -380,9 +381,12 @@ public class LuceneIndex extends Index {
}
private SortField convertSortField(final String sortString) {
- if ("relevance".equals(sortString)) {
+ if ("-<score>".equals(sortString)) {
return SortField.FIELD_SCORE;
}
+ if ("<score>".equals(sortString)) {
+ return FIELD_REVERSE_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);
diff --git a/src/docs/src/api/ddoc/nouveau.rst b/src/docs/src/api/ddoc/nouveau.rst
index b6c262c6d..fa9935e97 100644
--- a/src/docs/src/api/ddoc/nouveau.rst
+++ b/src/docs/src/api/ddoc/nouveau.rst
@@ -65,7 +65,7 @@
fieldname is the name of a string or double field. 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"``, ``"-foo"`` and
+ Some examples are ``"-<score>"``, ``"bar"``, ``"-foo"`` and
[``"-foo"``, ``"bar"``].
:query number top_n: Limit the number of facets returned by group, defaulting to 10
with a maximum of 1000.
diff --git a/test/elixir/test/config/nouveau.elixir b/test/elixir/test/config/nouveau.elixir
index 0066ce372..7fd6ff195 100644
--- a/test/elixir/test/config/nouveau.elixir
+++ b/test/elixir/test/config/nouveau.elixir
@@ -6,7 +6,9 @@
"search returns all items for GET",
"search returns all items for POST",
"search returns all items (paginated)",
- "search returns all matches for hello by relevance",
+ "search returns all matches for hello by relevance (implicit)",
+ "search returns all matches for hello by relevance (explicit)",
+ "search returns all matches for hello by reverse relevance (explicit)",
"search for foo:bar",
"search for numeric ranges with locales",
"multiple values for stored field",
diff --git a/test/elixir/test/nouveau_test.exs b/test/elixir/test/nouveau_test.exs
index 352270c22..609877b7b 100644
--- a/test/elixir/test/nouveau_test.exs
+++ b/test/elixir/test/nouveau_test.exs
@@ -194,7 +194,7 @@ defmodule NouveauTest do
end
@tag :with_db
- test "search returns all matches for hello by relevance", context do
+ test "search returns all matches for hello by relevance (implicit)", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
@@ -209,6 +209,38 @@ defmodule NouveauTest do
assert Enum.at(Enum.at(orders, 0), 0)["value"] > Enum.at(Enum.at(orders, 1), 0)["value"]
end
+ @tag :with_db
+ test "search returns all matches for hello by relevance (explicit)", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/foo/_nouveau/bar"
+ resp = Couch.get(url, query: %{q: "txt:hello", sort: "\"-<score>\"", include_docs: true})
+ assert_status_code(resp, 200)
+ ids = get_ids(resp)
+ orders = get_orders(resp)
+ # doc4 scores higher (more hello's)
+ assert ids == ["doc4", "doc3"]
+ assert Enum.at(Enum.at(orders, 0), 0)["value"] > Enum.at(Enum.at(orders, 1), 0)["value"]
+ end
+
+ @tag :with_db
+ test "search returns all matches for hello by reverse relevance (explicit)", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/foo/_nouveau/bar"
+ resp = Couch.get(url, query: %{q: "txt:hello", sort: "\"<score>\"", include_docs: true})
+ assert_status_code(resp, 200)
+ ids = get_ids(resp)
+ orders = get_orders(resp)
+ # doc4 scores lower (fewer hello's)
+ assert ids == ["doc3", "doc4"]
+ assert Enum.at(Enum.at(orders, 0), 0)["value"] < Enum.at(Enum.at(orders, 1), 0)["value"]
+ end
+
@tag :with_db
test "search returns all items for POST", context do
db_name = context[:db_name]