Fix npe when using source confirmed text query against missing field (#127414)
We should check for the field and statistics actually existing when checking matches and explanation with `match_only_text` fields closes: https://github.com/elastic/elasticsearch/issues/125635
This commit is contained in:
parent
83300ea1f1
commit
3d67e0e7ca
|
@ -0,0 +1,5 @@
|
|||
pr: 127414
|
||||
summary: Fix npe when using source confirmed text query against missing field
|
||||
area: Search
|
||||
type: bug
|
||||
issues: []
|
|
@ -267,7 +267,11 @@ public final class SourceConfirmedTextQuery extends Query {
|
|||
@Override
|
||||
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
|
||||
NumericDocValues norms = context.reader().getNormValues(field);
|
||||
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier(context).get(0);
|
||||
ScorerSupplier scorerSupplier = scorerSupplier(context);
|
||||
if (scorerSupplier == null) {
|
||||
return Explanation.noMatch("No matching phrase");
|
||||
}
|
||||
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier.get(0);
|
||||
if (scorer == null) {
|
||||
return Explanation.noMatch("No matching phrase");
|
||||
}
|
||||
|
@ -277,6 +281,7 @@ public final class SourceConfirmedTextQuery extends Query {
|
|||
}
|
||||
float phraseFreq = scorer.freq();
|
||||
Explanation freqExplanation = Explanation.match(phraseFreq, "phraseFreq=" + phraseFreq);
|
||||
assert simScorer != null;
|
||||
Explanation scoreExplanation = simScorer.explain(freqExplanation, getNormValue(norms, doc));
|
||||
return Explanation.match(
|
||||
scoreExplanation.getValue(),
|
||||
|
@ -321,7 +326,11 @@ public final class SourceConfirmedTextQuery extends Query {
|
|||
Weight innerWeight = in.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, 1);
|
||||
return innerWeight.matches(context, doc);
|
||||
}
|
||||
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier(context).get(0L);
|
||||
ScorerSupplier scorerSupplier = scorerSupplier(context);
|
||||
if (scorerSupplier == null) {
|
||||
return null;
|
||||
}
|
||||
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier.get(0L);
|
||||
if (scorer == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.lucene.queries.spans.SpanQuery;
|
|||
import org.apache.lucene.queries.spans.SpanTermQuery;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||
import org.apache.lucene.search.Matches;
|
||||
|
@ -101,6 +102,26 @@ public class SourceConfirmedTextQueryTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testMissingPhrase() throws Exception {
|
||||
try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(Lucene.STANDARD_ANALYZER))) {
|
||||
|
||||
Document doc = new Document();
|
||||
doc.add(new TextField("body", "a b c b a b c", Store.YES));
|
||||
w.addDocument(doc);
|
||||
|
||||
try (IndexReader reader = DirectoryReader.open(w)) {
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
PhraseQuery query = new PhraseQuery("missing_field", "b", "c");
|
||||
Query sourceConfirmedPhraseQuery = new SourceConfirmedTextQuery(query, SOURCE_FETCHER_PROVIDER, Lucene.STANDARD_ANALYZER);
|
||||
Explanation explanation = searcher.explain(sourceConfirmedPhraseQuery, 0);
|
||||
assertFalse(explanation.isMatch());
|
||||
|
||||
Weight weight = searcher.createWeight(query, ScoreMode.COMPLETE, 1);
|
||||
assertNull(weight.matches(getOnlyLeafReader(reader).getContext(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testPhrase() throws Exception {
|
||||
try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(Lucene.STANDARD_ANALYZER))) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue