public override TopDocs Rescore(IndexSearcher searcher, TopDocs firstPassTopDocs, int topN) { // Copy ScoreDoc[] and sort by ascending docID: ScoreDoc[] hits = (ScoreDoc[])firstPassTopDocs.ScoreDocs.Clone(); Array.Sort(hits, new ComparerAnonymousInnerClassHelper(this)); IList <AtomicReaderContext> leaves = searcher.IndexReader.Leaves; TopFieldCollector collector = TopFieldCollector.Create(sort, topN, true, true, true, false); // Now merge sort docIDs from hits, with reader's leaves: int hitUpto = 0; int readerUpto = -1; int endDoc = 0; int docBase = 0; FakeScorer fakeScorer = new FakeScorer(); while (hitUpto < hits.Length) { ScoreDoc hit = hits[hitUpto]; int docID = hit.Doc; AtomicReaderContext readerContext = null; while (docID >= endDoc) { readerUpto++; readerContext = leaves[readerUpto]; endDoc = readerContext.DocBase + readerContext.Reader.MaxDoc; } if (readerContext != null) { // We advanced to another segment: collector.SetNextReader(readerContext); collector.SetScorer(fakeScorer); docBase = readerContext.DocBase; } fakeScorer.score = hit.Score; fakeScorer.doc = docID - docBase; collector.Collect(fakeScorer.doc); hitUpto++; } return(collector.GetTopDocs()); }
public override bool Score(ICollector collector, int max) { bool more; Bucket tmp; FakeScorer fs = new FakeScorer(); // The internal loop will set the score and doc before calling collect. collector.SetScorer(fs); do { bucketTable.first = null; while (current != null) // more queued { // check prohibited & required if ((current.Bits & PROHIBITED_MASK) == 0) { // TODO: re-enable this if BQ ever sends us required // clauses //&& (current.bits & requiredMask) == requiredMask) { // NOTE: Lucene always passes max = // Integer.MAX_VALUE today, because we never embed // a BooleanScorer inside another (even though // that should work)... but in theory an outside // app could pass a different max so we must check // it: if (current.Doc >= max) { tmp = current; current = current.Next; tmp.Next = bucketTable.first; bucketTable.first = tmp; continue; } if (current.Coord >= minNrShouldMatch) { fs.score = (float)(current.Score * coordFactors[current.Coord]); fs.doc = current.Doc; fs.freq = current.Coord; collector.Collect(current.Doc); } } current = current.Next; // pop the queue } if (bucketTable.first != null) { current = bucketTable.first; bucketTable.first = current.Next; return(true); } // refill the queue more = false; end += BucketTable.SIZE; for (SubScorer sub = scorers; sub != null; sub = sub.Next) { if (sub.More) { sub.More = sub.Scorer.Score(sub.Collector, end); more |= sub.More; } } current = bucketTable.first; } while (current != null || more); return(false); }