30
30
import org .apache .lucene .index .ImpactsEnum ;
31
31
import org .apache .lucene .index .ImpactsSource ;
32
32
import org .apache .lucene .index .LeafReaderContext ;
33
+ import org .apache .lucene .index .NumericDocValues ;
33
34
import org .apache .lucene .index .PostingsEnum ;
34
35
import org .apache .lucene .index .SlowImpactsEnum ;
35
36
import org .apache .lucene .index .Term ;
38
39
import org .apache .lucene .index .Terms ;
39
40
import org .apache .lucene .index .TermsEnum ;
40
41
import org .apache .lucene .search .similarities .Similarity ;
42
+ import org .apache .lucene .search .similarities .Similarity .SimScorer ;
41
43
import org .apache .lucene .util .BytesRef ;
42
44
import org .apache .lucene .util .IOSupplier ;
43
45
import org .apache .lucene .util .PriorityQueue ;
@@ -259,9 +261,13 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
259
261
assert scorer instanceof TermScorer ;
260
262
freq = ((TermScorer ) scorer ).freq ();
261
263
}
262
- LeafSimScorer docScorer = new LeafSimScorer (simWeight , context .reader (), field , true );
263
264
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 );
265
271
return Explanation .match (
266
272
scoreExplanation .getValue (),
267
273
"weight("
@@ -334,27 +340,27 @@ public Scorer get(long leadCost) throws IOException {
334
340
return new ConstantScoreScorer (0f , scoreMode , DocIdSetIterator .empty ());
335
341
}
336
342
337
- LeafSimScorer simScorer = new LeafSimScorer ( simWeight , context .reader (), field , true );
343
+ NumericDocValues norms = context .reader (). getNormValues ( field );
338
344
339
345
// we must optimize this case (term not in segment), disjunctions require >= 2 subs
340
346
if (iterators .size () == 1 ) {
341
347
final TermScorer scorer ;
342
348
if (scoreMode == ScoreMode .TOP_SCORES ) {
343
- scorer = new TermScorer (impacts .get (0 ), simScorer );
349
+ scorer = new TermScorer (impacts .get (0 ), simWeight , norms );
344
350
} else {
345
- scorer = new TermScorer (iterators .get (0 ), simScorer );
351
+ scorer = new TermScorer (iterators .get (0 ), simWeight , norms );
346
352
}
347
353
float boost = termBoosts .get (0 );
348
354
return scoreMode == ScoreMode .COMPLETE_NO_SCORES || boost == 1f
349
355
? scorer
350
- : new FreqBoostTermScorer (boost , scorer , simScorer );
356
+ : new FreqBoostTermScorer (boost , scorer , simWeight , norms );
351
357
} else {
352
358
353
359
// we use termscorers + disjunction as an impl detail
354
360
DisiPriorityQueue queue = new DisiPriorityQueue (iterators .size ());
355
361
for (int i = 0 ; i < iterators .size (); i ++) {
356
362
PostingsEnum postings = iterators .get (i );
357
- final TermScorer termScorer = new TermScorer (postings , simScorer );
363
+ final TermScorer termScorer = new TermScorer (postings , simWeight , norms );
358
364
float boost = termBoosts .get (i );
359
365
final DisiWrapperFreq wrapper = new DisiWrapperFreq (termScorer , boost );
360
366
queue .add (wrapper );
@@ -368,8 +374,7 @@ public Scorer get(long leadCost) throws IOException {
368
374
boosts [i ] = termBoosts .get (i );
369
375
}
370
376
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 );
373
378
ImpactsDISI impactsDisi = new ImpactsDISI (iterator , maxScoreCache );
374
379
375
380
if (scoreMode == ScoreMode .TOP_SCORES ) {
@@ -379,7 +384,7 @@ public Scorer get(long leadCost) throws IOException {
379
384
iterator = impactsDisi ;
380
385
}
381
386
382
- return new SynonymScorer (queue , iterator , impactsDisi , simScorer );
387
+ return new SynonymScorer (queue , iterator , impactsDisi , simWeight , norms );
383
388
}
384
389
}
385
390
@@ -575,18 +580,21 @@ private static class SynonymScorer extends Scorer {
575
580
private final DocIdSetIterator iterator ;
576
581
private final MaxScoreCache maxScoreCache ;
577
582
private final ImpactsDISI impactsDisi ;
578
- private final LeafSimScorer simScorer ;
583
+ private final SimScorer scorer ;
584
+ private final NumericDocValues norms ;
579
585
580
586
SynonymScorer (
581
587
DisiPriorityQueue queue ,
582
588
DocIdSetIterator iterator ,
583
589
ImpactsDISI impactsDisi ,
584
- LeafSimScorer simScorer ) {
590
+ SimScorer scorer ,
591
+ NumericDocValues norms ) {
585
592
this .queue = queue ;
586
593
this .iterator = iterator ;
587
594
this .maxScoreCache = impactsDisi .getMaxScoreCache ();
588
595
this .impactsDisi = impactsDisi ;
589
- this .simScorer = simScorer ;
596
+ this .scorer = scorer ;
597
+ this .norms = norms ;
590
598
}
591
599
592
600
@ Override
@@ -605,7 +613,11 @@ float freq() throws IOException {
605
613
606
614
@ Override
607
615
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 );
609
621
}
610
622
611
623
@ Override
@@ -647,17 +659,20 @@ float freq() throws IOException {
647
659
private static class FreqBoostTermScorer extends FilterScorer {
648
660
final float boost ;
649
661
final TermScorer in ;
650
- final LeafSimScorer docScorer ;
662
+ final SimScorer scorer ;
663
+ final NumericDocValues norms ;
651
664
652
- public FreqBoostTermScorer (float boost , TermScorer in , LeafSimScorer docScorer ) {
665
+ public FreqBoostTermScorer (
666
+ float boost , TermScorer in , SimScorer scorer , NumericDocValues norms ) {
653
667
super (in );
654
668
if (Float .isNaN (boost ) || Float .compare (boost , 0f ) < 0 || Float .compare (boost , 1f ) > 0 ) {
655
669
throw new IllegalArgumentException (
656
670
"boost must be a positive float between 0 (exclusive) and 1 (inclusive)" );
657
671
}
658
672
this .boost = boost ;
659
673
this .in = in ;
660
- this .docScorer = docScorer ;
674
+ this .scorer = scorer ;
675
+ this .norms = norms ;
661
676
}
662
677
663
678
float freq () throws IOException {
@@ -666,8 +681,11 @@ float freq() throws IOException {
666
681
667
682
@ Override
668
683
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 );
671
689
}
672
690
673
691
@ Override
0 commit comments