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/01/10 17:04:48 UTC

[couchdb] branch import-nouveau-reorg updated (0180f1f44 -> 3b0eb245f)

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

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


    from 0180f1f44 continue reducing lucene-specific exposure
     new b0dc6e584 add our own DoubleRange class
     new 3b0eb245f abstract FieldDoc away

The 2 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.


Summary of changes:
 .../org/apache/couchdb/nouveau/api/SearchHit.java  |  8 +-
 .../apache/couchdb/nouveau/api/SearchRequest.java  |  9 +-
 .../apache/couchdb/nouveau/api/SearchResults.java  |  1 +
 .../couchdb/nouveau/api/document/DocField.java     |  7 +-
 .../nouveau/api/document/DoublePointDocField.java  |  3 +
 .../nouveau/api/document/StoredDocField.java       |  3 +
 .../nouveau/api/document/StringDocField.java       |  3 +
 .../couchdb/nouveau/api/document/TextDocField.java |  3 +
 .../nouveau/api/facet/range/DoubleRange.java       | 98 ++++++++++++++++++++++
 .../couchdb/nouveau/core/lucene9/Lucene9Index.java | 40 ++++++---
 .../apache/couchdb/nouveau/IntegrationTest.java    |  5 +-
 .../couchdb/nouveau/api/SearchRequestTest.java     |  2 +-
 12 files changed, 158 insertions(+), 24 deletions(-)
 create mode 100644 java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/facet/range/DoubleRange.java


[couchdb] 01/02: add our own DoubleRange class

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b0dc6e584cf254a246e0cb843cf3211e6292aaa6
Author: Robert Newson <rn...@apache.org>
AuthorDate: Tue Jan 10 15:06:16 2023 +0000

    add our own DoubleRange class
---
 .../apache/couchdb/nouveau/api/SearchRequest.java  |  2 +-
 .../apache/couchdb/nouveau/api/SearchResults.java  |  1 +
 .../couchdb/nouveau/api/document/DocField.java     |  7 +-
 .../nouveau/api/document/DoublePointDocField.java  |  3 +
 .../nouveau/api/document/StoredDocField.java       |  3 +
 .../nouveau/api/document/StringDocField.java       |  3 +
 .../couchdb/nouveau/api/document/TextDocField.java |  3 +
 .../nouveau/api/facet/range/DoubleRange.java       | 98 ++++++++++++++++++++++
 .../couchdb/nouveau/core/lucene9/Lucene9Index.java | 25 ++++--
 .../apache/couchdb/nouveau/IntegrationTest.java    |  2 +-
 .../couchdb/nouveau/api/SearchRequestTest.java     |  2 +-
 11 files changed, 140 insertions(+), 9 deletions(-)

diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java
index 556adbd58..29e3a5dac 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java
@@ -23,7 +23,7 @@ import javax.validation.constraints.NotNull;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-import org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange;
+import org.apache.couchdb.nouveau.api.facet.range.DoubleRange;
 import org.apache.couchdb.nouveau.l9x.lucene.search.FieldDoc;
 
 import io.dropwizard.jackson.JsonSnakeCase;
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchResults.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchResults.java
index db23e9d29..1bd696b06 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchResults.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchResults.java
@@ -39,6 +39,7 @@ public class SearchResults {
     private Map<@NotNull String, Map<@NotNull String, Number>> ranges;
 
     public SearchResults() {
+        // Jackson serialization
     }
 
     public void setTotalHits(final long totalHits) {
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DocField.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DocField.java
index 54cd244a8..76a9d42f6 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DocField.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DocField.java
@@ -16,14 +16,19 @@ package org.apache.couchdb.nouveau.api.document;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSubTypes;
 import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
+
+import io.dropwizard.jackson.JsonSnakeCase;
+
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "@type")
 @JsonSubTypes({
         @JsonSubTypes.Type(value = StringDocField.class, name = "string"),
         @JsonSubTypes.Type(value = TextDocField.class, name = "text"),
-        @JsonSubTypes.Type(value = DoublePointDocField.class, name = "double_point")
+        @JsonSubTypes.Type(value = DoublePointDocField.class, name = "double_point"),
+        @JsonSubTypes.Type(value = StoredDocField.class, name = "stored")
 })
+@JsonSnakeCase
 public abstract class DocField {
 
     protected String name;
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DoublePointDocField.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DoublePointDocField.java
index c36149f2d..454f429c8 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DoublePointDocField.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/DoublePointDocField.java
@@ -15,6 +15,9 @@ package org.apache.couchdb.nouveau.api.document;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import io.dropwizard.jackson.JsonSnakeCase;
+
+@JsonSnakeCase
 public class DoublePointDocField extends DocField {
 
     private double value;
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StoredDocField.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StoredDocField.java
index 1de57a04c..181c9364a 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StoredDocField.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StoredDocField.java
@@ -15,6 +15,9 @@ package org.apache.couchdb.nouveau.api.document;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import io.dropwizard.jackson.JsonSnakeCase;
+
+@JsonSnakeCase
 public final class StoredDocField extends DocField {
 
     private Object value;
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StringDocField.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StringDocField.java
index 6675bc50c..248effb6c 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StringDocField.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/StringDocField.java
@@ -15,6 +15,9 @@ package org.apache.couchdb.nouveau.api.document;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import io.dropwizard.jackson.JsonSnakeCase;
+
+@JsonSnakeCase
 public final class StringDocField extends DocField {
 
     private String value;
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/TextDocField.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/TextDocField.java
index bf5fa4404..94d17ce07 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/TextDocField.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/document/TextDocField.java
@@ -15,6 +15,9 @@ package org.apache.couchdb.nouveau.api.document;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import io.dropwizard.jackson.JsonSnakeCase;
+
+@JsonSnakeCase
 public final class TextDocField extends DocField {
 
     private String value;
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/facet/range/DoubleRange.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/facet/range/DoubleRange.java
new file mode 100644
index 000000000..fa836d2c0
--- /dev/null
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/facet/range/DoubleRange.java
@@ -0,0 +1,98 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.couchdb.nouveau.api.facet.range;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import io.dropwizard.jackson.JsonSnakeCase;
+
+@JsonSnakeCase
+public final class DoubleRange {
+
+    private String label;
+
+    private double min;
+
+    private boolean minInclusive = true;
+
+    private double max;
+
+    private boolean maxInclusive = true;
+
+    public DoubleRange() {
+        // Jackson serialization
+    }
+
+    public DoubleRange(String label, double min, boolean minInclusive, double max, boolean maxInclusive) {
+        this.label = label;
+        this.min = min;
+        this.minInclusive = minInclusive;
+        this.max = max;
+        this.maxInclusive = maxInclusive;
+    }
+
+    @JsonProperty
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    @JsonProperty
+    public double getMin() {
+        return min;
+    }
+
+    public void setMin(double min) {
+        this.min = min;
+    }
+
+    @JsonProperty
+    public boolean getMinInclusive() {
+        return minInclusive;
+    }
+
+    public void setMinInclusive(boolean minInclusive) {
+        this.minInclusive = minInclusive;
+    }
+
+    @JsonProperty
+    public double getMax() 
+    {
+        return max;
+    }
+
+    public void setMax(double max) {
+        this.max = max;
+    }
+
+    @JsonProperty
+    public boolean getMaxInclusive() {
+        return maxInclusive;
+    }
+
+    public void setMaxInclusive(boolean maxInclusive) {
+        this.maxInclusive = maxInclusive;
+    }
+
+    @Override
+    public String toString() {
+        return "DoubleRange [label=" + label + ", min=" + min + ", minInclusive=" + minInclusive + ", max=" + max
+                + ", maxInclusive=" + maxInclusive + "]";
+    }
+        
+}
+
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java
index e49ff98d9..e6e9f42ac 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java
@@ -38,13 +38,13 @@ import org.apache.couchdb.nouveau.api.document.DoublePointDocField;
 import org.apache.couchdb.nouveau.api.document.StoredDocField;
 import org.apache.couchdb.nouveau.api.document.StringDocField;
 import org.apache.couchdb.nouveau.api.document.TextDocField;
+import org.apache.couchdb.nouveau.api.facet.range.DoubleRange;
 import org.apache.couchdb.nouveau.core.Index;
 import org.apache.couchdb.nouveau.core.QueryParser;
 import org.apache.couchdb.nouveau.core.QueryParserException;
 import org.apache.couchdb.nouveau.l9x.lucene.analysis.Analyzer;
 import org.apache.couchdb.nouveau.l9x.lucene.document.Document;
 import org.apache.couchdb.nouveau.l9x.lucene.document.DoublePoint;
-import org.apache.couchdb.nouveau.l9x.lucene.document.Field;
 import org.apache.couchdb.nouveau.l9x.lucene.document.SortedDocValuesField;
 import org.apache.couchdb.nouveau.l9x.lucene.document.StoredField;
 import org.apache.couchdb.nouveau.l9x.lucene.document.StringField;
@@ -57,7 +57,6 @@ import org.apache.couchdb.nouveau.l9x.lucene.facet.FacetsCollectorManager;
 import org.apache.couchdb.nouveau.l9x.lucene.facet.LabelAndValue;
 import org.apache.couchdb.nouveau.l9x.lucene.facet.StringDocValuesReaderState;
 import org.apache.couchdb.nouveau.l9x.lucene.facet.StringValueFacetCounts;
-import org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange;
 import org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRangeFacetCounts;
 import org.apache.couchdb.nouveau.l9x.lucene.index.IndexWriter;
 import org.apache.couchdb.nouveau.l9x.lucene.index.IndexWriterConfig;
@@ -83,7 +82,6 @@ import org.apache.couchdb.nouveau.l9x.lucene.util.BytesRef;
 
 class Lucene9Index extends Index {
 
-    private static final DoubleRange[] EMPTY_DOUBLE_RANGE_ARRAY = new DoubleRange[0];
     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+)>)?$");
@@ -245,14 +243,31 @@ class Lucene9Index extends Index {
             final Map<String, Map<String, Number>> rangesMap = new HashMap<String, Map<String, Number>>(
                     searchRequest.getRanges().size());
             for (final Entry<String, List<DoubleRange>> entry : searchRequest.getRanges().entrySet()) {
-                final DoubleRangeFacetCounts counts = new DoubleRangeFacetCounts(entry.getKey(), fc,
-                        entry.getValue().toArray(EMPTY_DOUBLE_RANGE_ARRAY));
+                final DoubleRangeFacetCounts counts = new DoubleRangeFacetCounts(entry.getKey(), fc, convertDoubleRanges(entry.getValue()));
                 rangesMap.put(entry.getKey(), collectFacets(counts, searchRequest.getTopN(), entry.getKey()));
             }
             searchResults.setRanges(rangesMap);
         }
     }
 
+    private org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange[] convertDoubleRanges(final List<DoubleRange> ranges) {
+        final org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange[] result = new org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange[ranges.size()];
+        for (int i = 0; i < ranges.size(); i++) {
+            result[i] = convertDoubleRange(ranges.get(i));
+        }
+        return result;
+    }
+
+    private org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange convertDoubleRange(final DoubleRange range) {
+        return new org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange(
+            range.getLabel(),
+            range.getMin(),
+            range.getMinInclusive(),
+            range.getMax(),
+            range.getMaxInclusive()
+        );
+    }
+
     private Map<String, Number> collectFacets(final Facets facets, final int topN, final String dim)
             throws IOException {
         final FacetResult topChildren = facets.getTopChildren(topN, dim);
diff --git a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java
index 81ac17e56..d67153f12 100644
--- a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java
+++ b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java
@@ -30,7 +30,7 @@ import org.apache.couchdb.nouveau.api.SearchRequest;
 import org.apache.couchdb.nouveau.api.SearchResults;
 import org.apache.couchdb.nouveau.api.document.StringDocField;
 import org.apache.couchdb.nouveau.api.document.TextDocField;
-import org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange;
+import org.apache.couchdb.nouveau.api.facet.range.DoubleRange;
 import org.apache.couchdb.nouveau.l9x.lucene.search.FieldDoc;
 import org.apache.couchdb.nouveau.l9x.lucene.search.TotalHits;
 import org.apache.couchdb.nouveau.l9x.lucene.search.TotalHits.Relation;
diff --git a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/api/SearchRequestTest.java b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/api/SearchRequestTest.java
index e6986ee8a..886f376de 100644
--- a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/api/SearchRequestTest.java
+++ b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/api/SearchRequestTest.java
@@ -6,7 +6,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.couchdb.nouveau.l9x.lucene.facet.range.DoubleRange;
+import org.apache.couchdb.nouveau.api.facet.range.DoubleRange;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 


[couchdb] 02/02: abstract FieldDoc away

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3b0eb245fb5ac3511154583f44fc213a25a8b8f1
Author: Robert Newson <rn...@apache.org>
AuthorDate: Tue Jan 10 16:45:05 2023 +0000

    abstract FieldDoc away
---
 .../java/org/apache/couchdb/nouveau/api/SearchHit.java    |  8 ++++----
 .../org/apache/couchdb/nouveau/api/SearchRequest.java     |  7 +++----
 .../apache/couchdb/nouveau/core/lucene9/Lucene9Index.java | 15 +++++++++------
 .../java/org/apache/couchdb/nouveau/IntegrationTest.java  |  3 ++-
 4 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchHit.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchHit.java
index deeb4536d..8b3413ee3 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchHit.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchHit.java
@@ -14,12 +14,12 @@
 package org.apache.couchdb.nouveau.api;
 
 import java.util.Collection;
+import java.util.List;
 
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 
 import org.apache.couchdb.nouveau.api.document.DocField;
-import org.apache.couchdb.nouveau.l9x.lucene.search.FieldDoc;
 
 import io.dropwizard.jackson.JsonSnakeCase;
 
@@ -30,7 +30,7 @@ public class SearchHit {
     private String id;
 
     @NotNull
-    private FieldDoc order;
+    private Object[] order;
 
     @NotNull
     private Collection<@NotNull DocField> fields;
@@ -38,7 +38,7 @@ public class SearchHit {
     public SearchHit() {
     }
 
-    public SearchHit(final String id, final FieldDoc order, final Collection<DocField> fields) {
+    public SearchHit(final String id, final Object[] order, final Collection<DocField> fields) {
         this.id = id;
         this.order = order;
         this.fields = fields;
@@ -48,7 +48,7 @@ public class SearchHit {
         return id;
     }
 
-    public FieldDoc getOrder() {
+    public Object[] getOrder() {
         return order;
     }
 
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java
index 29e3a5dac..9fbdeb0ae 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/api/SearchRequest.java
@@ -24,7 +24,6 @@ import javax.validation.constraints.NotNull;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import org.apache.couchdb.nouveau.api.facet.range.DoubleRange;
-import org.apache.couchdb.nouveau.l9x.lucene.search.FieldDoc;
 
 import io.dropwizard.jackson.JsonSnakeCase;
 
@@ -46,7 +45,7 @@ public class SearchRequest {
 
     private Map<@NotEmpty String, List<@NotNull DoubleRange>> ranges;
 
-    private FieldDoc after;
+    private Object[] after;
 
     @Min(1)
     @Max(100)
@@ -131,12 +130,12 @@ public class SearchRequest {
         return topN;
     }
 
-    public void setAfter(final FieldDoc after) {
+    public void setAfter(final Object[]after) {
         this.after = after;
     }
 
     @JsonProperty
-    public FieldDoc getAfter() {
+    public Object[] getAfter() {
         return after;
     }
 
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java
index e6e9f42ac..eee041f53 100644
--- a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/lucene9/Lucene9Index.java
@@ -172,12 +172,15 @@ class Lucene9Index extends Index {
     private CollectorManager<?, ? extends TopDocs> hitCollector(final SearchRequest searchRequest) {
         final Sort sort = toSort(searchRequest);
 
-        final FieldDoc after = searchRequest.getAfter();
-        if (after != null) {
+        final Object[] fields = searchRequest.getAfter();
+        final FieldDoc after;
+        if (fields == null) {
+            after = null;
+        } else {
             if (getLastSortField(sort).getReverse()) {
-                after.doc = 0;
+                after = new FieldDoc(0, 0.0f, fields);
             } else {
-                after.doc = Integer.MAX_VALUE;
+                after = new FieldDoc(Integer.MAX_VALUE, 0.0f, fields);
             }
         }
 
@@ -216,8 +219,8 @@ class Lucene9Index extends Index {
                     fields.add(luceneFieldToDocField(field));
                 }
             }
-
-            hits.add(new SearchHit(doc.get("_id"), (FieldDoc) scoreDoc, fields));
+            final FieldDoc fieldDoc = (FieldDoc) scoreDoc;
+            hits.add(new SearchHit(doc.get("_id"), fieldDoc.fields, fields));
         }
 
         searchResults.setTotalHits(topDocs.totalHits.value);
diff --git a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java
index d67153f12..9005bf9ef 100644
--- a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java
+++ b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/IntegrationTest.java
@@ -17,6 +17,7 @@ import static org.apache.couchdb.nouveau.api.LuceneVersion.LUCENE_9;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -94,7 +95,7 @@ public class IntegrationTest {
         searchRequest.setCounts(List.of("bar"));
         searchRequest.setRanges(Map.of("baz", List.of(new DoubleRange("0 to 100 inc", 0.0, true, 100.0, true))));
         searchRequest.setTopN(2);
-        searchRequest.setAfter(new FieldDoc(0, Float.NaN, new Object[]{1.0f, new BytesRef("a")}));
+        searchRequest.setAfter(new Object[]{1.0f, new BytesRef("a")});
 
         response =
                 APP.client().target(String.format("%s/index/%s/search", url, indexName))