Constructors Summary |
---|
public BooleanScorer2(Similarity similarity, int minNrShouldMatch, boolean allowDocsOutOfOrder)Create a BooleanScorer2.
super(similarity);
if (minNrShouldMatch < 0) {
throw new IllegalArgumentException("Minimum number of optional scorers should not be negative");
}
coordinator = new Coordinator();
this.minNrShouldMatch = minNrShouldMatch;
this.allowDocsOutOfOrder = allowDocsOutOfOrder;
|
public BooleanScorer2(Similarity similarity, int minNrShouldMatch)Create a BooleanScorer2.
In no required scorers are added,
at least one of the optional scorers will have to match during the search.
this(similarity, minNrShouldMatch, false);
|
public BooleanScorer2(Similarity similarity)Create a BooleanScorer2.
In no required scorers are added,
at least one of the optional scorers will have to match during the search.
this(similarity, 0, false);
|
Methods Summary |
---|
public void | add(org.apache.lucene.search.Scorer scorer, boolean required, boolean prohibited)
if (!prohibited) {
coordinator.maxCoord++;
}
if (required) {
if (prohibited) {
throw new IllegalArgumentException("scorer cannot be required and prohibited");
}
requiredScorers.add(scorer);
} else if (prohibited) {
prohibitedScorers.add(scorer);
} else {
optionalScorers.add(scorer);
}
|
private org.apache.lucene.search.Scorer | addProhibitedScorers(org.apache.lucene.search.Scorer requiredCountingSumScorer)Returns the scorer to be used for match counting and score summing.
Uses the given required scorer and the prohibitedScorers.
return (prohibitedScorers.size() == 0)
? requiredCountingSumScorer // no prohibited
: new ReqExclScorer(requiredCountingSumScorer,
((prohibitedScorers.size() == 1)
? (Scorer) prohibitedScorers.get(0)
: new DisjunctionSumScorer(prohibitedScorers)));
|
private org.apache.lucene.search.Scorer | countingConjunctionSumScorer(java.util.List requiredScorers)
// each scorer from the list counted as a single matcher
final int requiredNrMatchers = requiredScorers.size();
ConjunctionScorer cs = new ConjunctionScorer(defaultSimilarity) {
private int lastScoredDoc = -1;
public float score() throws IOException {
if (this.doc() >= lastScoredDoc) {
lastScoredDoc = this.doc();
coordinator.nrMatchers += requiredNrMatchers;
}
// All scorers match, so defaultSimilarity super.score() always has 1 as
// the coordination factor.
// Therefore the sum of the scores of the requiredScorers
// is used as score.
return super.score();
}
};
Iterator rsi = requiredScorers.iterator();
while (rsi.hasNext()) {
cs.add((Scorer) rsi.next());
}
return cs;
|
private org.apache.lucene.search.Scorer | countingDisjunctionSumScorer(java.util.List scorers, int minNrShouldMatch)
return new DisjunctionSumScorer(scorers, minNrShouldMatch) {
private int lastScoredDoc = -1;
public float score() throws IOException {
if (this.doc() >= lastScoredDoc) {
lastScoredDoc = this.doc();
coordinator.nrMatchers += super.nrMatchers;
}
return super.score();
}
};
|
public int | doc() return countingSumScorer.doc();
|
private org.apache.lucene.search.Scorer | dualConjunctionSumScorer(org.apache.lucene.search.Scorer req1, org.apache.lucene.search.Scorer req2) // non counting.
ConjunctionScorer cs = new ConjunctionScorer(defaultSimilarity);
// All scorers match, so defaultSimilarity always has 1 as
// the coordination factor.
// Therefore the sum of the scores of two scorers
// is used as score.
cs.add(req1);
cs.add(req2);
return cs;
|
public org.apache.lucene.search.Explanation | explain(int doc)Throws an UnsupportedOperationException.
TODO: Implement an explanation of the coordination factor.
throw new UnsupportedOperationException();
/* How to explain the coordination factor?
initCountingSumScorer();
return countingSumScorer.explain(doc); // misses coord factor.
*/
|
private void | initCountingSumScorer()Initialize the match counting scorer that sums all the
scores.
When "counting" is used in a name it means counting the number
of matching scorers.
When "sum" is used in a name it means score value summing
over the matching scorers
coordinator.init();
countingSumScorer = makeCountingSumScorer();
|
private org.apache.lucene.search.Scorer | makeCountingSumScorer()Returns the scorer to be used for match counting and score summing.
Uses requiredScorers, optionalScorers and prohibitedScorers. // each scorer counted as a single matcher
return (requiredScorers.size() == 0)
? makeCountingSumScorerNoReq()
: makeCountingSumScorerSomeReq();
|
private org.apache.lucene.search.Scorer | makeCountingSumScorerNoReq() // No required scorers
if (optionalScorers.size() == 0) {
return new NonMatchingScorer(); // no clauses or only prohibited clauses
} else { // No required scorers. At least one optional scorer.
// minNrShouldMatch optional scorers are required, but at least 1
int nrOptRequired = (minNrShouldMatch < 1) ? 1 : minNrShouldMatch;
if (optionalScorers.size() < nrOptRequired) {
return new NonMatchingScorer(); // fewer optional clauses than minimum (at least 1) that should match
} else { // optionalScorers.size() >= nrOptRequired, no required scorers
Scorer requiredCountingSumScorer =
(optionalScorers.size() > nrOptRequired)
? countingDisjunctionSumScorer(optionalScorers, nrOptRequired)
: // optionalScorers.size() == nrOptRequired (all optional scorers are required), no required scorers
(optionalScorers.size() == 1)
? new SingleMatchScorer((Scorer) optionalScorers.get(0))
: countingConjunctionSumScorer(optionalScorers);
return addProhibitedScorers(requiredCountingSumScorer);
}
}
|
private org.apache.lucene.search.Scorer | makeCountingSumScorerSomeReq() // At least one required scorer.
if (optionalScorers.size() < minNrShouldMatch) {
return new NonMatchingScorer(); // fewer optional clauses than minimum that should match
} else if (optionalScorers.size() == minNrShouldMatch) { // all optional scorers also required.
ArrayList allReq = new ArrayList(requiredScorers);
allReq.addAll(optionalScorers);
return addProhibitedScorers(countingConjunctionSumScorer(allReq));
} else { // optionalScorers.size() > minNrShouldMatch, and at least one required scorer
Scorer requiredCountingSumScorer =
(requiredScorers.size() == 1)
? new SingleMatchScorer((Scorer) requiredScorers.get(0))
: countingConjunctionSumScorer(requiredScorers);
if (minNrShouldMatch > 0) { // use a required disjunction scorer over the optional scorers
return addProhibitedScorers(
dualConjunctionSumScorer( // non counting
requiredCountingSumScorer,
countingDisjunctionSumScorer(
optionalScorers,
minNrShouldMatch)));
} else { // minNrShouldMatch == 0
return new ReqOptSumScorer(
addProhibitedScorers(requiredCountingSumScorer),
((optionalScorers.size() == 1)
? new SingleMatchScorer((Scorer) optionalScorers.get(0))
: countingDisjunctionSumScorer(optionalScorers, 1))); // require 1 in combined, optional scorer.
}
}
|
public boolean | next()
if (countingSumScorer == null) {
initCountingSumScorer();
}
return countingSumScorer.next();
|
public void | score(org.apache.lucene.search.HitCollector hc)Scores and collects all matching documents.
if (allowDocsOutOfOrder && requiredScorers.size() == 0
&& prohibitedScorers.size() < 32) {
// fall back to BooleanScorer, scores documents somewhat out of order
BooleanScorer bs = new BooleanScorer(getSimilarity(), minNrShouldMatch);
Iterator si = optionalScorers.iterator();
while (si.hasNext()) {
bs.add((Scorer) si.next(), false /* required */, false /* prohibited */);
}
si = prohibitedScorers.iterator();
while (si.hasNext()) {
bs.add((Scorer) si.next(), false /* required */, true /* prohibited */);
}
bs.score(hc);
} else {
if (countingSumScorer == null) {
initCountingSumScorer();
}
while (countingSumScorer.next()) {
hc.collect(countingSumScorer.doc(), score());
}
}
|
protected boolean | score(org.apache.lucene.search.HitCollector hc, int max)Expert: Collects matching documents in a range.
Note that {@link #next()} must be called once before this method is
called for the first time.
// null pointer exception when next() was not called before:
int docNr = countingSumScorer.doc();
while (docNr < max) {
hc.collect(docNr, score());
if (! countingSumScorer.next()) {
return false;
}
docNr = countingSumScorer.doc();
}
return true;
|
public float | score()
coordinator.initDoc();
float sum = countingSumScorer.score();
return sum * coordinator.coordFactor();
|
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.
if (countingSumScorer == null) {
initCountingSumScorer();
}
return countingSumScorer.skipTo(target);
|