ソースを参照

fix missing override for matches in ProfileWeight (#92360)

profiling wraps a weight object in order to mix-in timings. This PR fixes a missing override of matches. In addition I added test coverage for other overrides.
Hendrik Muhs 2 年 前
コミット
92af5fefc6

+ 5 - 0
docs/changelog/92360.yaml

@@ -0,0 +1,5 @@
+pr: 92360
+summary: Fix missing override for matches in `ProfileWeight`
+area: Search
+type: bug
+issues: []

+ 4 - 0
server/src/main/java/org/elasticsearch/search/profile/query/ProfileWeight.java

@@ -11,6 +11,7 @@ package org.elasticsearch.search.profile.query;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.BulkScorer;
 import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.Matches;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.ScorerSupplier;
@@ -116,4 +117,7 @@ public final class ProfileWeight extends Weight {
         return false;
     }
 
+    public Matches matches(LeafReaderContext context, int doc) throws IOException {
+        return subQueryWeight.matches(context, doc);
+    }
 }

+ 97 - 0
server/src/test/java/org/elasticsearch/search/profile/query/ProfileScorerTests.java

@@ -8,10 +8,14 @@
 
 package org.elasticsearch.search.profile.query;
 
+import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.MultiReader;
 import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Matches;
+import org.apache.lucene.search.MatchesIterator;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
@@ -19,6 +23,9 @@ import org.apache.lucene.search.Weight;
 import org.elasticsearch.test.ESTestCase;
 
 import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
 
 public class ProfileScorerTests extends ESTestCase {
 
@@ -56,6 +63,85 @@ public class ProfileScorerTests extends ESTestCase {
         }
     }
 
+    private static class FakeWeight extends Weight {
+
+        protected FakeWeight(Query query) {
+            super(query);
+        }
+
+        @Override
+        public Explanation explain(LeafReaderContext context, int doc) throws IOException {
+            return Explanation.match(1, "fake_description");
+        }
+
+        @Override
+        public Scorer scorer(LeafReaderContext context) throws IOException {
+            FakeScorer fakeScorer = new FakeScorer(this);
+            fakeScorer.maxScore = 42f;
+            return fakeScorer;
+        }
+
+        @Override
+        public boolean isCacheable(LeafReaderContext ctx) {
+            return false;
+        }
+
+        @Override
+        public Matches matches(LeafReaderContext context, int doc) throws IOException {
+            return new Matches() {
+                @Override
+                public MatchesIterator getMatches(String field) throws IOException {
+                    return new MatchesIterator() {
+                        @Override
+                        public boolean next() throws IOException {
+                            return false;
+                        }
+
+                        @Override
+                        public int startPosition() {
+                            return 42;
+                        }
+
+                        @Override
+                        public int endPosition() {
+                            return 43;
+                        }
+
+                        @Override
+                        public int startOffset() throws IOException {
+                            return 44;
+                        }
+
+                        @Override
+                        public int endOffset() throws IOException {
+                            return 45;
+                        }
+
+                        @Override
+                        public MatchesIterator getSubMatches() throws IOException {
+                            return null;
+                        }
+
+                        @Override
+                        public Query getQuery() {
+                            return parentQuery;
+                        }
+                    };
+                }
+
+                @Override
+                public Collection<Matches> getSubMatches() {
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public Iterator<String> iterator() {
+                    return null;
+                }
+            };
+        }
+    }
+
     public void testPropagateMinCompetitiveScore() throws IOException {
         Query query = new MatchAllDocsQuery();
         Weight weight = query.createWeight(new IndexSearcher(new MultiReader()), ScoreMode.TOP_SCORES, 1f);
@@ -78,4 +164,15 @@ public class ProfileScorerTests extends ESTestCase {
         fakeScorer.maxScore = 42f;
         assertEquals(42f, profileScorer.getMaxScore(DocIdSetIterator.NO_MORE_DOCS), 0f);
     }
+
+    // tests that ProfileWeight correctly propagates the wrapped inner weight
+    public void testPropagateSubWeight() throws IOException {
+        Query query = new MatchAllDocsQuery();
+        Weight fakeWeight = new FakeWeight(query);
+        QueryProfileBreakdown profile = new QueryProfileBreakdown();
+        ProfileWeight profileWeight = new ProfileWeight(query, fakeWeight, profile);
+        assertEquals(42f, profileWeight.scorer(null).getMaxScore(DocIdSetIterator.NO_MORE_DOCS), 0f);
+        assertEquals(42, profileWeight.matches(null, 1).getMatches("some_field").startPosition());
+        assertEquals("fake_description", profileWeight.explain(null, 1).getDescription());
+    }
 }