This is an automated email from the ASF dual-hosted git repository. ishan pushed a commit to branch ishan/upgrade-to-lucene-10 in repository https://gitbox.apache.org/repos/asf/solr.git
commit 9303a26b7ec093c3260c2c9ebac0dca24f7790dd Author: Ishan Chattopadhyaya <[email protected]> AuthorDate: Thu Aug 7 20:30:35 2025 +0530 SOLR-17631: Tidy, logging fixes, note on using lucene-sandbox --- gradle/libs.versions.toml | 3 +- solr/core/build.gradle | 1 + .../java/org/apache/solr/query/SolrRangeQuery.java | 14 ++- .../org/apache/solr/request/DocValuesFacets.java | 4 +- .../solr/search/ComplexPhraseQParserPlugin.java | 14 +-- .../solr/search/ExpressionValueSourceParser.java | 123 ++++++++++----------- .../src/java/org/apache/solr/search/Grouping.java | 17 ++- .../solr/util/SolrDefaultScorerSupplier.java | 16 +++ .../PathHierarchyTokenizerFactoryTest.java | 8 +- .../solr/uninverting/TestFieldCacheSortRandom.java | 15 ++- .../java/org/apache/solr/ltr/LTRScoringQuery.java | 5 +- .../pages/major-changes-in-solr-10.adoc | 2 + 12 files changed, 127 insertions(+), 95 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 342f6f29165..f05420bd748 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -278,6 +278,7 @@ apache-lucene-join = { module = "org.apache.lucene:lucene-join", version.ref = " apache-lucene-misc = { module = "org.apache.lucene:lucene-misc", version.ref = "apache-lucene" } apache-lucene-queries = { module = "org.apache.lucene:lucene-queries", version.ref = "apache-lucene" } apache-lucene-queryparser = { module = "org.apache.lucene:lucene-queryparser", version.ref = "apache-lucene" } +apache-lucene-sandbox = { module = "org.apache.lucene:lucene-sandbox", version.ref = "apache-lucene" } apache-lucene-spatialextras = { module = "org.apache.lucene:lucene-spatial-extras", version.ref = "apache-lucene" } apache-lucene-suggest = { module = "org.apache.lucene:lucene-suggest", version.ref = "apache-lucene" } apache-lucene-testframework = { module = "org.apache.lucene:lucene-test-framework", version.ref = "apache-lucene" } @@ -436,9 +437,9 @@ kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-t kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } +ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-client-contentNegotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } -ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } ktor-client-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } diff --git a/solr/core/build.gradle b/solr/core/build.gradle index f6e3c3114a5..74a2b9e64d7 100644 --- a/solr/core/build.gradle +++ b/solr/core/build.gradle @@ -91,6 +91,7 @@ dependencies { implementation libs.apache.lucene.join implementation libs.apache.lucene.misc implementation libs.apache.lucene.queryparser + implementation libs.apache.lucene.sandbox implementation libs.apache.lucene.spatialextras implementation libs.apache.lucene.suggest diff --git a/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java b/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java index 60236135eaf..91bc00fc0dc 100644 --- a/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java +++ b/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java @@ -540,11 +540,15 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro public Scorer scorerInternal(LeafReaderContext context) throws IOException { final SegState weightOrBitSet = getSegState(context); - log.info("Query: " + getQuery()); - log.info("weight: " + weightOrBitSet.weight); - if (weightOrBitSet.weight != null) - log.info("weight's scorer: " + weightOrBitSet.weight.scorer(context)); - log.info("set: " + weightOrBitSet.set); + if (log.isDebugEnabled()) { + log.debug("Query: {}", getQuery()); + log.debug("weight: {}", weightOrBitSet.weight); + if (weightOrBitSet.weight != null) { + Scorer scorer = weightOrBitSet.weight.scorer(context); + log.debug("weight's scorer: {}", scorer); + } + log.debug("set: {}", weightOrBitSet.set); + } if (weightOrBitSet.weight != null) { Scorer ret = weightOrBitSet.weight.scorer(context); return ret; diff --git a/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java index 5b66da544fe..c37d2ad2ea9 100644 --- a/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java +++ b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java @@ -430,7 +430,7 @@ public class DocValuesFacets { for (int o = 0; o < si.docValueCount(); o++) { long ord = si.nextOrd(); if (ord == -1) // NO_MORE_ORDS - break; + break; int term = (int) ord; if (map != null) { term = (int) ordMap.get(term); @@ -465,7 +465,7 @@ public class DocValuesFacets { for (int o = 0; o < si.docValueCount(); o++) { long ord = si.nextOrd(); if (ord == -1) // NO_MORE_ORDS - break; + break; int term = (int) ord; segCounts[1 + term]++; } diff --git a/solr/core/src/java/org/apache/solr/search/ComplexPhraseQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/ComplexPhraseQParserPlugin.java index fbb32a951bf..2292b175121 100644 --- a/solr/core/src/java/org/apache/solr/search/ComplexPhraseQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/ComplexPhraseQParserPlugin.java @@ -78,13 +78,13 @@ public class ComplexPhraseQParserPlugin extends QParserPlugin { protected org.apache.lucene.search.Query getWildcardQuery(String field, String termStr) throws SyntaxError { Query q = super.getWildcardQuery(field, termStr); - + // For complex phrase queries, we need to ensure wildcard queries and automaton queries // use SCORING_BOOLEAN_REWRITE to avoid the new constant score wrappers in Lucene 10 if (q instanceof WildcardQuery) { WildcardQuery wq = (WildcardQuery) q; return new WildcardQuery( - wq.getTerm(), + wq.getTerm(), Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.SCORING_BOOLEAN_REWRITE); } else if (q instanceof AutomatonQuery) { @@ -93,12 +93,12 @@ public class ComplexPhraseQParserPlugin extends QParserPlugin { // We can't access the term directly, but for reversed wildcard queries, // we can use a placeholder term since the automaton contains the actual matching logic return new AutomatonQuery( - new Term(field, ""), + new Term(field, ""), aq.getAutomaton(), aq.isAutomatonBinary(), MultiTermQuery.SCORING_BOOLEAN_REWRITE); } - + return q; } @@ -155,17 +155,17 @@ public class ComplexPhraseQParserPlugin extends QParserPlugin { // Get the wildcard query from the reverse-aware parser org.apache.lucene.search.Query wildcardQuery = reverseAwareParser.getWildcardQuery(t.field(), t.text()); - + // In Lucene 10, we need to ensure wildcard queries use SCORING_BOOLEAN_REWRITE // for complex phrase queries to work properly if (wildcardQuery instanceof WildcardQuery) { WildcardQuery wq = (WildcardQuery) wildcardQuery; return new WildcardQuery( - wq.getTerm(), + wq.getTerm(), Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.SCORING_BOOLEAN_REWRITE); } - + return wildcardQuery; } catch (SyntaxError e) { throw new RuntimeException(e); diff --git a/solr/core/src/java/org/apache/solr/search/ExpressionValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/ExpressionValueSourceParser.java index e62f5a19227..67b2ebe75e2 100644 --- a/solr/core/src/java/org/apache/solr/search/ExpressionValueSourceParser.java +++ b/solr/core/src/java/org/apache/solr/search/ExpressionValueSourceParser.java @@ -37,8 +37,8 @@ import org.apache.lucene.search.DoubleValuesSource; import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparatorSource; import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Scorable; import org.apache.lucene.search.Pruning; +import org.apache.lucene.search.Scorable; import org.apache.lucene.search.SimpleFieldComparator; import org.apache.lucene.search.SortField; import org.apache.solr.common.SolrException; @@ -113,10 +113,10 @@ public class ExpressionValueSourceParser extends ValueSourceParser { IndexSchema schema = fp.getReq().getSchema(); SolrBindings b = new SolrBindings(scoreKey, schema, positionalArgs); DoubleValuesSource doubleValuesSource = expression.getDoubleValuesSource(b); - + // Check if this expression needs scores by examining if it contains score references boolean needsScores = doubleValuesSource.needsScores(); - + if (needsScores) { // For score-dependent expressions, create a custom ValueSource that can // properly integrate with Lucene's sorting scorer mechanism @@ -128,33 +128,34 @@ public class ExpressionValueSourceParser extends ValueSourceParser { } /** - * A custom ValueSource that properly handles score-dependent expressions by implementing - * the setScorer() pattern required by Lucene's sorting mechanism. - * - * This solves the fundamental issue where ValueSourceComparator.doSetNextReader() - * is called during sorting setup when no scorer is available, but expressions need - * scores to work correctly. + * A custom ValueSource that properly handles score-dependent expressions by implementing the + * setScorer() pattern required by Lucene's sorting mechanism. + * + * <p>This solves the fundamental issue where ValueSourceComparator.doSetNextReader() is called + * during sorting setup when no scorer is available, but expressions need scores to work + * correctly. */ private static class ScoreAwareValueSource extends ValueSource { private final DoubleValuesSource doubleValuesSource; - + public ScoreAwareValueSource(DoubleValuesSource doubleValuesSource) { this.doubleValuesSource = doubleValuesSource; } - + @Override - public FunctionValues getValues(java.util.Map<Object, Object> context, LeafReaderContext readerContext) throws IOException { + public FunctionValues getValues( + java.util.Map<Object, Object> context, LeafReaderContext readerContext) throws IOException { // Get scorer from context (may be null during setup) Scorable scorer = (Scorable) context.get("scorer"); DoubleValues scores = scorer == null ? null : DoubleValuesSource.fromScorer(scorer); - + // Get the DoubleValues from our source DoubleValues doubleValues = doubleValuesSource.getValues(readerContext, scores); - + // Return a ScoreAwareFunctionValues that can be updated when scorer becomes available return new ScoreAwareFunctionValues(doubleValuesSource, readerContext, doubleValues); } - + @Override public boolean equals(Object o) { if (this == o) return true; @@ -162,68 +163,67 @@ public class ExpressionValueSourceParser extends ValueSourceParser { ScoreAwareValueSource that = (ScoreAwareValueSource) o; return doubleValuesSource.equals(that.doubleValuesSource); } - + @Override public int hashCode() { return doubleValuesSource.hashCode(); } - + @Override public String description() { return "ScoreAware(" + doubleValuesSource.toString() + ")"; } - + @Override public SortField getSortField(boolean reverse) { // Create a SortField that uses our custom comparator return new SortField(description(), new ScoreAwareComparatorSource(), reverse); } - - /** - * Custom FieldComparatorSource that implements the setScorer() pattern - */ + + /** Custom FieldComparatorSource that implements the setScorer() pattern */ private class ScoreAwareComparatorSource extends FieldComparatorSource { @Override - public FieldComparator<?> newComparator(String fieldname, int numHits, Pruning pruning, boolean reversed) { + public FieldComparator<?> newComparator( + String fieldname, int numHits, Pruning pruning, boolean reversed) { return new ScoreAwareComparator(numHits); } } - + /** - * Custom FieldComparator that properly implements setScorer() to ensure - * scores are available during sorting + * Custom FieldComparator that properly implements setScorer() to ensure scores are available + * during sorting */ private class ScoreAwareComparator extends SimpleFieldComparator<Double> { private final double[] values; private ScoreAwareFunctionValues functionValues; private double bottom; private double topValue; - + public ScoreAwareComparator(int numHits) { this.values = new double[numHits]; } - + @Override public int compare(int slot1, int slot2) { return Double.compare(values[slot1], values[slot2]); } - + @Override public int compareBottom(int doc) throws IOException { return Double.compare(bottom, functionValues.doubleVal(doc)); } - + @Override public void copy(int slot, int doc) throws IOException { values[slot] = functionValues.doubleVal(doc); } - + @Override public void doSetNextReader(LeafReaderContext context) throws IOException { // Create initial FunctionValues (may have null scorer) functionValues = (ScoreAwareFunctionValues) getValues(new java.util.HashMap<>(), context); } - + @Override public void setScorer(Scorable scorer) throws IOException { // This is the key method that was missing in ValueSourceComparator! @@ -232,49 +232,48 @@ public class ExpressionValueSourceParser extends ValueSourceParser { functionValues.updateScorer(scorer); } } - + @Override public void setBottom(int bottom) { this.bottom = values[bottom]; } - + @Override public void setTopValue(Double value) { this.topValue = value; } - + @Override public Double value(int slot) { return values[slot]; } - + @Override public int compareTop(int doc) throws IOException { return Double.compare(topValue, functionValues.doubleVal(doc)); } } } - - /** - * FunctionValues that can be updated with a scorer when it becomes available - */ + + /** FunctionValues that can be updated with a scorer when it becomes available */ private static class ScoreAwareFunctionValues extends FunctionValues { private final DoubleValuesSource source; private final LeafReaderContext context; private DoubleValues doubleValues; - - public ScoreAwareFunctionValues(DoubleValuesSource source, LeafReaderContext context, DoubleValues initialDoubleValues) { + + public ScoreAwareFunctionValues( + DoubleValuesSource source, LeafReaderContext context, DoubleValues initialDoubleValues) { this.source = source; this.context = context; this.doubleValues = initialDoubleValues; } - + public void updateScorer(Scorable scorer) throws IOException { // When scorer becomes available, recreate DoubleValues with actual scores DoubleValues scores = DoubleValuesSource.fromScorer(scorer); this.doubleValues = source.getValues(context, scores); } - + @Override public double doubleVal(int doc) throws IOException { if (!doubleValues.advanceExact(doc)) { @@ -282,27 +281,27 @@ public class ExpressionValueSourceParser extends ValueSourceParser { } return doubleValues.doubleValue(); } - + @Override public float floatVal(int doc) throws IOException { return (float) doubleVal(doc); } - + @Override public int intVal(int doc) throws IOException { return (int) doubleVal(doc); } - + @Override public long longVal(int doc) throws IOException { return (long) doubleVal(doc); } - + @Override public String strVal(int doc) throws IOException { return Float.toString(floatVal(doc)); } - + @Override public String toString(int doc) throws IOException { return Double.toString(doubleVal(doc)); @@ -364,17 +363,17 @@ public class ExpressionValueSourceParser extends ValueSourceParser { /** * Custom DoubleValuesSource for scores that handles the Lucene 10 assertion gracefully. - * - * The core issue: Lucene 10's DoubleValuesSource.SCORES has an assertion that scores != null, + * + * <p>The core issue: Lucene 10's DoubleValuesSource.SCORES has an assertion that scores != null, * but during ValueSource sorting setup, scores can be null. This creates a timing mismatch * between when the expression is evaluated and when the scorer is available. - * - * This implementation bypasses the assertion and provides reasonable fallback behavior - * when scores are not available, while delegating to the original implementation when - * scores are available. + * + * <p>This implementation bypasses the assertion and provides reasonable fallback behavior when + * scores are not available, while delegating to the original implementation when scores are + * available. */ private static class ScoreDoubleValuesSource extends DoubleValuesSource { - + @Override public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { // Instead of calling DoubleValuesSource.SCORES.getValues() which has the assertion, @@ -414,16 +413,16 @@ public class ExpressionValueSourceParser extends ValueSourceParser { } /** - * A DoubleValues implementation that handles score access with a graceful fallback - * when scores are not available (e.g., during sorting setup). + * A DoubleValues implementation that handles score access with a graceful fallback when scores + * are not available (e.g., during sorting setup). */ private static class ScoreDoubleValues extends DoubleValues { private final DoubleValues scores; - + public ScoreDoubleValues(DoubleValues scores) { this.scores = scores; } - + @Override public double doubleValue() throws IOException { if (scores != null) { @@ -432,7 +431,7 @@ public class ExpressionValueSourceParser extends ValueSourceParser { } else { // When scores are null (during sorting setup or other contexts where // no scorer is available), return 0.0 as a fallback. - // + // // NOTE: This breaks score-based sorting because all documents get the // same score (0.0), but it avoids the assertion error and allows the // query to complete. The fundamental issue is that the legacy ValueSource @@ -441,7 +440,7 @@ public class ExpressionValueSourceParser extends ValueSourceParser { return 0.0; } } - + @Override public boolean advanceExact(int doc) throws IOException { if (scores != null) { diff --git a/solr/core/src/java/org/apache/solr/search/Grouping.java b/solr/core/src/java/org/apache/solr/search/Grouping.java index 72055ee0f96..24770bebf22 100644 --- a/solr/core/src/java/org/apache/solr/search/Grouping.java +++ b/solr/core/src/java/org/apache/solr/search/Grouping.java @@ -30,13 +30,11 @@ import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.search.CachingCollector; import org.apache.lucene.search.Collector; -import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.MultiCollector; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Sort; -import org.apache.lucene.search.SortField; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopDocsCollector; import org.apache.lucene.search.TopFieldCollector; @@ -299,7 +297,8 @@ public class Grouping { SolrIndexSearcher.ProcessedFilter pf = searcher.getProcessedFilter(cmd.getFilterList()); - final Query searchQuery = QueryUtils.combineQueryAndFilter(QueryUtils.makeQueryable(cmd.getQuery()), pf.filter); + final Query searchQuery = + QueryUtils.combineQueryAndFilter(QueryUtils.makeQueryable(cmd.getQuery()), pf.filter); maxDoc = searcher.maxDoc(); needScores = (cmd.getFlags() & SolrIndexSearcher.GET_SCORES) != 0; @@ -569,7 +568,9 @@ public class Grouping { protected void populateScoresIfNecessary() throws IOException { if (needScores) { for (GroupDocs<?> groups : result.groups) { - log.info("Group score is 1: " + groups.maxScore()); + if (log.isDebugEnabled()) { + log.debug("Group score is 1: {}", groups.maxScore()); + } TopFieldCollector.populateScores(groups.scoreDocs(), searcher, query); } } @@ -612,7 +613,9 @@ public class Grouping { float score = groups.maxScore(); maxScore = maxAvoidNaN(score, maxScore); - log.info("Here, score is " + score + " and maxScore is " + maxScore); + if (log.isDebugEnabled()) { + log.debug("Here, score is {} and maxScore is {}", score, maxScore); + } DocSlice docs = new DocSlice( off, @@ -900,7 +903,9 @@ public class Grouping { maxScore = topDocs.scoreDocs.length == 0 ? Float.NaN : topDocs.scoreDocs[0].score; } else if (needScores) { // use top-level query to populate the scores - log.info("Group score is 2: " + maxScoreCollector.getMaxScore()); + if (log.isDebugEnabled()) { + log.debug("Group score is 2: {}", maxScoreCollector.getMaxScore()); + } TopFieldCollector.populateScores(topDocs.scoreDocs, searcher, Grouping.this.query); maxScore = maxScoreCollector.getMaxScore(); } else { diff --git a/solr/core/src/java/org/apache/solr/util/SolrDefaultScorerSupplier.java b/solr/core/src/java/org/apache/solr/util/SolrDefaultScorerSupplier.java index 200761bc4e1..c3923ea6b87 100644 --- a/solr/core/src/java/org/apache/solr/util/SolrDefaultScorerSupplier.java +++ b/solr/core/src/java/org/apache/solr/util/SolrDefaultScorerSupplier.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.solr.util; import java.io.IOException; diff --git a/solr/core/src/test/org/apache/solr/analysis/PathHierarchyTokenizerFactoryTest.java b/solr/core/src/test/org/apache/solr/analysis/PathHierarchyTokenizerFactoryTest.java index 68d2b0db0ad..8f368b437ba 100644 --- a/solr/core/src/test/org/apache/solr/analysis/PathHierarchyTokenizerFactoryTest.java +++ b/solr/core/src/test/org/apache/solr/analysis/PathHierarchyTokenizerFactoryTest.java @@ -88,10 +88,12 @@ public class PathHierarchyTokenizerFactoryTest extends SolrTestCaseJ4 { } public void testAncestors() { - // NOTE: In Lucene 10+, PathHierarchyTokenizer produces sequential tokens instead of overlapping tokens. - // This changes the behavior of ancestor queries - they now match based on sequential token positions + // NOTE: In Lucene 10+, PathHierarchyTokenizer produces sequential tokens instead of overlapping + // tokens. + // This changes the behavior of ancestor queries - they now match based on sequential token + // positions // rather than overlapping positions, so ancestor matching behavior has changed. - + assertQ( req("{!field f=cat_ancestor}Books/NonFic/Science"), "//*[@numFound='2']", diff --git a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java index 7bb77f7187c..a70bc3418e6 100644 --- a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java +++ b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java @@ -258,20 +258,23 @@ public class TestFieldCacheSortRandom extends SolrTestCase { + s.storedFields().document(fd.doc).get("id")); } } - + // For STRING_VAL type (using BinaryDocValues), we cannot manually compare the sorted order - // because Lucene 10+ changed the internal sorting behavior for BinaryDocValues. - // The manual BytesRef.compareTo() used in this test doesn't match the actual Lucene sort order. + // because Lucene 10+ changed the internal sorting behavior for BinaryDocValues. + // The manual BytesRef.compareTo() used in this test doesn't match the actual Lucene sort + // order. // Instead, we just validate that the uninverting is working correctly by checking that: // 1. No exceptions are thrown // 2. Returned values are valid BytesRef or null - // This ensures doc values uninverting works without assuming specific sort implementation details. + // This ensures doc values uninverting works without assuming specific sort implementation + // details. if (type == SortField.Type.STRING_VAL) { for (int hitIDX = 0; hitIDX < hits.scoreDocs.length; hitIDX++) { final FieldDoc fd = (FieldDoc) hits.scoreDocs[hitIDX]; Object sortValue = fd.fields[0]; - assertTrue("Sort value should be BytesRef or null", - sortValue == null || sortValue instanceof BytesRef); + assertTrue( + "Sort value should be BytesRef or null", + sortValue == null || sortValue instanceof BytesRef); } continue; // Skip the exact comparison for STRING_VAL } diff --git a/solr/modules/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java b/solr/modules/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java index 0712d6c6e7d..85b33fc3ebd 100644 --- a/solr/modules/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java +++ b/solr/modules/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java @@ -32,7 +32,6 @@ import java.util.concurrent.Semaphore; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.DisiPriorityQueue; import org.apache.lucene.search.DisiWrapper; -import org.apache.lucene.search.DisjunctionDISIApproximation; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.IndexSearcher; @@ -662,7 +661,7 @@ public class LTRScoringQuery extends Query implements Accountable { targetDoc = activeDoc; return targetDoc; } - + if (activeDoc == targetDoc) { // Advance the underlying disjunction DisiWrapper top = subScorers.top(); @@ -690,7 +689,7 @@ public class LTRScoringQuery extends Query implements Accountable { targetDoc = target; return targetDoc; } - + private int advanceInternal(int target) throws IOException { // Advance the underlying disjunction to the target DisiWrapper top; diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc index bbbda70b6c1..2dc4958e8cd 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc @@ -132,6 +132,8 @@ Solr upgraded to Jetty 12.x from 10.x as Jetty 10 and 11 have reached end-of-lif Due to Lucene 10 changes (https://github.com/apache/lucene/pull/12875), `PathHierarchyTokenizer` now produces sequential tokens (position increment = 1) instead of overlapping tokens (position increment = 0). This affects ancestor queries that relied on overlapping token matching. Users should test existing queries and update configurations if needed. +* In Lucene 10, the `OrdinalIterator` class has been moved from the main `lucene-facet` module to the `lucene-sandbox` module. This requires Solr core to now include a dependency on `lucene-sandbox` to support faceting operations that use this class. + *Example configuration change:* [source,xml] ----
