DisjunctionSumScorerpublic class DisjunctionSumScorer extends Scorer A Scorer for OR like queries, counterpart of 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 ScorerDocQueue | scorerDocQueueThe scorerDocQueue contains all subscorers ordered by their current doc(),
with the minimum at the top.
The scorerDocQueue is initialized the first time next() or skipTo() is called.
An exhausted scorer is immediately removed from the scorerDocQueue.
If less than the minimumNrMatchers scorers
remain in the scorerDocQueue 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 | queueSize | 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 scorerDocQueue .
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 scorerDocQueue has at least minimumNrMatchers
available. At least the scorer with the minimum document number will be advanced.
do { // repeat until minimum nr of matchers
currentDoc = scorerDocQueue.topDoc();
currentScore = scorerDocQueue.topScore();
nrMatchers = 1;
do { // Until all subscorers are after currentDoc
if (! scorerDocQueue.topNextAndAdjustElsePop()) {
if (--queueSize == 0) {
break; // nothing more to advance, check for last match.
}
}
if (scorerDocQueue.topDoc() != currentDoc) {
break; // All remaining subscorers are after currentDoc.
}
currentScore += scorerDocQueue.topScore();
nrMatchers++;
} while (true);
if (nrMatchers >= minimumNrMatchers) {
return true;
} else if (queueSize < minimumNrMatchers) {
return false;
}
} while (true);
| public int | doc() return currentDoc;
| public org.apache.lucene.search.Explanation | explain(int doc)
Explanation res = new Explanation();
Iterator ssi = subScorers.iterator();
float sumScore = 0.0f;
int nrMatches = 0;
while (ssi.hasNext()) {
Explanation es = ((Scorer) ssi.next()).explain(doc);
if (es.getValue() > 0.0f) { // indicates match
sumScore += es.getValue();
nrMatches++;
}
res.addDetail(es);
}
if (nrMatchers >= minimumNrMatchers) {
res.setValue(sumScore);
res.setDescription("sum over at least " + minimumNrMatchers
+ " of " + subScorers.size() + ":");
} else {
res.setValue(0.0f);
res.setDescription(nrMatches + " match(es) but at least "
+ minimumNrMatchers + " of "
+ subScorers.size() + " needed");
}
return res;
| private void | initScorerDocQueue()Called the first time next() or skipTo() is called to
initialize scorerDocQueue .
Iterator si = subScorers.iterator();
scorerDocQueue = new ScorerDocQueue(nrScorers);
queueSize = 0;
while (si.hasNext()) {
Scorer se = (Scorer) si.next();
if (se.next()) { // doc() method will be used in scorerDocQueue.
if (scorerDocQueue.insert(se)) {
queueSize++;
}
}
}
| public boolean | next()
if (scorerDocQueue == null) {
initScorerDocQueue();
}
return (scorerDocQueue.size() >= minimumNrMatchers)
&& 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 void | score(org.apache.lucene.search.HitCollector hc)Scores and collects all matching documents.
while (next()) {
hc.collect(currentDoc, currentScore);
}
| protected boolean | score(org.apache.lucene.search.HitCollector hc, int max)Expert: Collects matching documents in a range. Hook for optimization.
Note that {@link #next()} must be called once before this method is called
for the first time.
while (currentDoc < max) {
hc.collect(currentDoc, currentScore);
if (!next()) {
return false;
}
}
return true;
| 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 (scorerDocQueue == null) {
initScorerDocQueue();
}
if (queueSize < minimumNrMatchers) {
return false;
}
if (target <= currentDoc) {
return true;
}
do {
if (scorerDocQueue.topDoc() >= target) {
return advanceAfterCurrent();
} else if (! scorerDocQueue.topSkipToAndAdjustElsePop(target)) {
if (--queueSize < minimumNrMatchers) {
return false;
}
}
} while (true);
|
|