DisjunctionSumScorerpublic class DisjunctionSumScorer extends Scorer A Scorer for OR like queries, counterpart of Lucene's ConjunctionScorer .
This Scorer implements {@link Scorer#skipTo(int)} and uses skipTo() on the given Scorers. |
Fields Summary |
---|
private final int | nrScorersThe number of subscorers. | protected final List | subScorersThe subscorers. | private final int | minimumNrMatchersThe minimum number of scorers that should match. | private ScorerQueue | scorerQueueThe scorerQueue contains all subscorers ordered by their current doc(),
with the minimum at the top.
The scorerQueue is initialized the first time next() or skipTo() is called.
An exhausted scorer is immediately removed from the scorerQueue.
If less than the minimumNrMatchers scorers
remain in the scorerQueue next() and skipTo() return false.
After each to call to next() or skipTo()
currentSumScore is the total score of the current matching doc,
nrMatchers is the number of matching scorers,
and all scorers are after the matching doc, or are exhausted. | private int | currentDocThe document number of the current match. | protected int | nrMatchersThe number of subscorers that provide the current match. | private float | currentScore |
Constructors Summary |
---|
public DisjunctionSumScorer(List subScorers, int minimumNrMatchers)Construct a DisjunctionScorer .
super(null);
nrScorers = subScorers.size();
if (minimumNrMatchers <= 0) {
throw new IllegalArgumentException("Minimum nr of matchers must be positive");
}
if (nrScorers <= 1) {
throw new IllegalArgumentException("There must be at least 2 subScorers");
}
this.minimumNrMatchers = minimumNrMatchers;
this.subScorers = subScorers;
| public DisjunctionSumScorer(List subScorers)Construct a DisjunctionScorer , using one as the minimum number
of matching subscorers.
this(subScorers, 1);
|
Methods Summary |
---|
protected boolean | advanceAfterCurrent()Advance all subscorers after the current document determined by the
top of the scorerQueue .
Repeat until at least the minimum number of subscorers match on the same
document and all subscorers are after that document or are exhausted.
On entry the scorerQueue has at least minimumNrMatchers
available. At least the scorer with the minimum document number will be advanced.
do { // repeat until minimum nr of matchers
Scorer top = (Scorer) scorerQueue.top();
currentDoc = top.doc();
currentScore = top.score();
nrMatchers = 1;
do { // Until all subscorers are after currentDoc
if (top.next()) {
scorerQueue.adjustTop();
} else {
scorerQueue.pop();
if (scorerQueue.size() < (minimumNrMatchers - nrMatchers)) {
// Not enough subscorers left for a match on this document,
// and also no more chance of any further match.
return false;
}
if (scorerQueue.size() == 0) {
break; // nothing more to advance, check for last match.
}
}
top = (Scorer) scorerQueue.top();
if (top.doc() != currentDoc) {
break; // All remaining subscorers are after currentDoc.
} else {
currentScore += top.score();
nrMatchers++;
}
} while (true);
if (nrMatchers >= minimumNrMatchers) {
return true;
} else if (scorerQueue.size() < minimumNrMatchers) {
return false;
}
} while (true);
| public int | doc() return currentDoc;
| public org.apache.lucene.search.Explanation | explain(int doc)Gives and explanation for the score of a given document.
Explanation res = new Explanation();
res.setDescription("At least " + minimumNrMatchers + " of");
Iterator ssi = subScorers.iterator();
while (ssi.hasNext()) {
res.addDetail( ((Scorer) ssi.next()).explain(doc));
}
return res;
| private void | initScorerQueue()Called the first time next() or skipTo() is called to
initialize scorerQueue .
Iterator si = subScorers.iterator();
scorerQueue = new ScorerQueue(nrScorers);
while (si.hasNext()) {
Scorer se = (Scorer) si.next();
if (se.next()) { // doc() method will be used in scorerQueue.
scorerQueue.insert(se);
}
}
| public boolean | next()
if (scorerQueue == null) {
initScorerQueue();
}
if (scorerQueue.size() < minimumNrMatchers) {
return false;
} else {
return advanceAfterCurrent();
}
| public int | nrMatchers()Returns the number of subscorers matching the current document.
Initially invalid, until {@link #next()} is called the first time.
return nrMatchers;
| public float | score()Returns the score of the current document matching the query.
Initially invalid, until {@link #next()} is called the first time. return currentScore;
| public boolean | skipTo(int target)Skips to the first match beyond the current whose document number is
greater than or equal to a given target.
When this method is used the {@link #explain(int)} method should not be used.
The implementation uses the skipTo() method on the subscorers.
if (scorerQueue == null) {
initScorerQueue();
}
if (scorerQueue.size() < minimumNrMatchers) {
return false;
}
if (target <= currentDoc) {
target = currentDoc + 1;
}
do {
Scorer top = (Scorer) scorerQueue.top();
if (top.doc() >= target) {
return advanceAfterCurrent();
} else if (top.skipTo(target)) {
scorerQueue.adjustTop();
} else {
scorerQueue.pop();
if (scorerQueue.size() < minimumNrMatchers) {
return false;
}
}
} while (true);
|
|