3030import org .apache .lucene .index .ImpactsEnum ;
3131import org .apache .lucene .index .ImpactsSource ;
3232import org .apache .lucene .index .LeafReaderContext ;
33+ import org .apache .lucene .index .NumericDocValues ;
3334import org .apache .lucene .index .PostingsEnum ;
3435import org .apache .lucene .index .SlowImpactsEnum ;
3536import org .apache .lucene .index .Term ;
3839import org .apache .lucene .index .Terms ;
3940import org .apache .lucene .index .TermsEnum ;
4041import org .apache .lucene .search .similarities .Similarity ;
42+ import org .apache .lucene .search .similarities .Similarity .SimScorer ;
4143import org .apache .lucene .util .BytesRef ;
4244import org .apache .lucene .util .IOSupplier ;
4345import org .apache .lucene .util .PriorityQueue ;
@@ -259,9 +261,13 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
259261 assert scorer instanceof TermScorer ;
260262 freq = ((TermScorer ) scorer ).freq ();
261263 }
262- LeafSimScorer docScorer = new LeafSimScorer (simWeight , context .reader (), field , true );
263264 Explanation freqExplanation = Explanation .match (freq , "termFreq=" + freq );
264- Explanation scoreExplanation = docScorer .explain (doc , freqExplanation );
265+ NumericDocValues norms = context .reader ().getNormValues (field );
266+ long norm = 1L ;
267+ if (norms != null && norms .advanceExact (doc )) {
268+ norm = norms .longValue ();
269+ }
270+ Explanation scoreExplanation = simWeight .explain (freqExplanation , norm );
265271 return Explanation .match (
266272 scoreExplanation .getValue (),
267273 "weight("
@@ -334,27 +340,27 @@ public Scorer get(long leadCost) throws IOException {
334340 return new ConstantScoreScorer (0f , scoreMode , DocIdSetIterator .empty ());
335341 }
336342
337- LeafSimScorer simScorer = new LeafSimScorer ( simWeight , context .reader (), field , true );
343+ NumericDocValues norms = context .reader (). getNormValues ( field );
338344
339345 // we must optimize this case (term not in segment), disjunctions require >= 2 subs
340346 if (iterators .size () == 1 ) {
341347 final TermScorer scorer ;
342348 if (scoreMode == ScoreMode .TOP_SCORES ) {
343- scorer = new TermScorer (impacts .get (0 ), simScorer );
349+ scorer = new TermScorer (impacts .get (0 ), simWeight , norms );
344350 } else {
345- scorer = new TermScorer (iterators .get (0 ), simScorer );
351+ scorer = new TermScorer (iterators .get (0 ), simWeight , norms );
346352 }
347353 float boost = termBoosts .get (0 );
348354 return scoreMode == ScoreMode .COMPLETE_NO_SCORES || boost == 1f
349355 ? scorer
350- : new FreqBoostTermScorer (boost , scorer , simScorer );
356+ : new FreqBoostTermScorer (boost , scorer , simWeight , norms );
351357 } else {
352358
353359 // we use termscorers + disjunction as an impl detail
354360 DisiPriorityQueue queue = new DisiPriorityQueue (iterators .size ());
355361 for (int i = 0 ; i < iterators .size (); i ++) {
356362 PostingsEnum postings = iterators .get (i );
357- final TermScorer termScorer = new TermScorer (postings , simScorer );
363+ final TermScorer termScorer = new TermScorer (postings , simWeight , norms );
358364 float boost = termBoosts .get (i );
359365 final DisiWrapperFreq wrapper = new DisiWrapperFreq (termScorer , boost );
360366 queue .add (wrapper );
@@ -368,8 +374,7 @@ public Scorer get(long leadCost) throws IOException {
368374 boosts [i ] = termBoosts .get (i );
369375 }
370376 ImpactsSource impactsSource = mergeImpacts (impacts .toArray (new ImpactsEnum [0 ]), boosts );
371- MaxScoreCache maxScoreCache =
372- new MaxScoreCache (impactsSource , simScorer .getSimScorer ());
377+ MaxScoreCache maxScoreCache = new MaxScoreCache (impactsSource , simWeight );
373378 ImpactsDISI impactsDisi = new ImpactsDISI (iterator , maxScoreCache );
374379
375380 if (scoreMode == ScoreMode .TOP_SCORES ) {
@@ -379,7 +384,7 @@ public Scorer get(long leadCost) throws IOException {
379384 iterator = impactsDisi ;
380385 }
381386
382- return new SynonymScorer (queue , iterator , impactsDisi , simScorer );
387+ return new SynonymScorer (queue , iterator , impactsDisi , simWeight , norms );
383388 }
384389 }
385390
@@ -575,18 +580,21 @@ private static class SynonymScorer extends Scorer {
575580 private final DocIdSetIterator iterator ;
576581 private final MaxScoreCache maxScoreCache ;
577582 private final ImpactsDISI impactsDisi ;
578- private final LeafSimScorer simScorer ;
583+ private final SimScorer scorer ;
584+ private final NumericDocValues norms ;
579585
580586 SynonymScorer (
581587 DisiPriorityQueue queue ,
582588 DocIdSetIterator iterator ,
583589 ImpactsDISI impactsDisi ,
584- LeafSimScorer simScorer ) {
590+ SimScorer scorer ,
591+ NumericDocValues norms ) {
585592 this .queue = queue ;
586593 this .iterator = iterator ;
587594 this .maxScoreCache = impactsDisi .getMaxScoreCache ();
588595 this .impactsDisi = impactsDisi ;
589- this .simScorer = simScorer ;
596+ this .scorer = scorer ;
597+ this .norms = norms ;
590598 }
591599
592600 @ Override
@@ -605,7 +613,11 @@ float freq() throws IOException {
605613
606614 @ Override
607615 public float score () throws IOException {
608- return simScorer .score (iterator .docID (), freq ());
616+ long norm = 1L ;
617+ if (norms != null && norms .advanceExact (iterator .docID ())) {
618+ norm = norms .longValue ();
619+ }
620+ return scorer .score (freq (), norm );
609621 }
610622
611623 @ Override
@@ -647,17 +659,20 @@ float freq() throws IOException {
647659 private static class FreqBoostTermScorer extends FilterScorer {
648660 final float boost ;
649661 final TermScorer in ;
650- final LeafSimScorer docScorer ;
662+ final SimScorer scorer ;
663+ final NumericDocValues norms ;
651664
652- public FreqBoostTermScorer (float boost , TermScorer in , LeafSimScorer docScorer ) {
665+ public FreqBoostTermScorer (
666+ float boost , TermScorer in , SimScorer scorer , NumericDocValues norms ) {
653667 super (in );
654668 if (Float .isNaN (boost ) || Float .compare (boost , 0f ) < 0 || Float .compare (boost , 1f ) > 0 ) {
655669 throw new IllegalArgumentException (
656670 "boost must be a positive float between 0 (exclusive) and 1 (inclusive)" );
657671 }
658672 this .boost = boost ;
659673 this .in = in ;
660- this .docScorer = docScorer ;
674+ this .scorer = scorer ;
675+ this .norms = norms ;
661676 }
662677
663678 float freq () throws IOException {
@@ -666,8 +681,11 @@ float freq() throws IOException {
666681
667682 @ Override
668683 public float score () throws IOException {
669- assert docID () != DocIdSetIterator .NO_MORE_DOCS ;
670- return docScorer .score (in .docID (), freq ());
684+ long norm = 1L ;
685+ if (norms != null && norms .advanceExact (in .docID ())) {
686+ norm = norms .longValue ();
687+ }
688+ return scorer .score (freq (), norm );
671689 }
672690
673691 @ Override
0 commit comments