📄 inaccuratebooleanscorer2.java
字号:
final int requiredNrMatchers = requiredScorers.size();
ConjunctionScorer cs = new ConjunctionScorer(defaultSimilarity);
// All scorers match, so defaultSimilarity super.score() 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;
}
/**
* Returns the scorer to be used for match counting and score summing. Uses
* requiredScorers, optionalScorers and prohibitedScorers.
*/
private Scorer makeCountingSumScorer() { // each scorer counted as a
// single matcher
return (requiredScorers.size() == 0) ? makeCountingSumScorerNoReq()
: makeCountingSumScorerSomeReq();
}
private 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);
}
}
}
@SuppressWarnings("unchecked")
private 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.
}
}
}
/**
* Returns the scorer to be used for match counting and score summing. Uses
* the given required scorer and the prohibitedScorers.
*
* @param requiredCountingSumScorer
* A required scorer already built.
*/
private Scorer addProhibitedScorers(Scorer requiredCountingSumScorer) {
return (prohibitedScorers.size() == 0) ? requiredCountingSumScorer // no
// prohibited
: new ReqExclScorer(
requiredCountingSumScorer,
((prohibitedScorers.size() == 1) ? (Scorer) prohibitedScorers
.get(0)
: new DisjunctionSumScorer(prohibitedScorers)));
}
/**
* Scores and collects all matching documents.
*
* @param hc
* The collector to which all matching documents are passed
* through {@link HitCollector#collect(int, float)}. <br>
* When this method is used the {@link #explain(int)} method
* should not be used.
*/
public void score(HitCollector hc) throws IOException {
if (countingSumScorer == null) {
initCountingSumScorer();
}
while (countingSumScorer.next()) {
hc.collect(countingSumScorer.doc(), score());
}
}
public InaccurateResultAggregation getInaccurateTopAggregation(
HitCollector hc, boolean ascending) throws IOException {
// DeltaTime dt = new DeltaTime();
if (countingSumScorer == null) {
initCountingSumScorer();
}
int lastDocID = 0;
boolean reachedTheEnd = true;
int numberOfRecordsFetched = 0;
while (countingSumScorer.next()) {
lastDocID = countingSumScorer.doc();
float score = score();
hc.collect(lastDocID, score);
numberOfRecordsFetched++;
if (numberOfRecordsFetched >= maxNumberOfDocs) {
reachedTheEnd = !countingSumScorer.next();
break;
}
}
// System.out.println(dt.getTimeElasped());
/*
* This method might cast the rest away. So it might be inaccurate.
*/
return new InaccurateResultAggregation(lastDocID, ascending,
reachedTheEnd, numberOfRecordsFetched, numberOfRecordsFetched);
}
public InaccurateResultAggregation getAccurateBottomAggregation(
HitCollector hc, boolean ascending) throws IOException {
// DeltaTime dt = new DeltaTime();
if (countingSumScorer == null) {
initCountingSumScorer();
}
LinkedList<ResultNode> resultNodes = new LinkedList<ResultNode>();
boolean isFull = false;
int lastDocID = 0;
int index = 0;
int numberOfRecordsFound = 0;
while (countingSumScorer.next()) {
lastDocID = countingSumScorer.doc();
float score = score();
resultNodes.add(new ResultNode(lastDocID, score));
if (isFull) {
resultNodes.removeFirst();
}
index++;
numberOfRecordsFound++;
if (index >= maxNumberOfDocs) {
isFull = true;
index = 0;
// break;
}
}
for (ResultNode resultNode : resultNodes) {
hc.collect(resultNode.getDoc(), resultNode.getScore());
}
// System.out.println(dt.getTimeElasped());
/*
* Since this method runs full scan against all matched docs, it's
* accurate at all.
*/
return new InaccurateResultAggregation(lastDocID, ascending, true,
resultNodes.size(), numberOfRecordsFound);
}
/**
* Expert: Collects matching documents in a range. <br>
* Note that {@link #next()} must be called once before this method is
* called for the first time.
*
* @param hc
* The collector to which all matching documents are passed
* through {@link HitCollector#collect(int, float)}.
* @param max
* Do not score documents past this.
* @return true if more matching documents may remain.
*/
protected boolean score(HitCollector hc, int max) throws IOException {
// 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 int doc() {
return countingSumScorer.doc();
}
public boolean next() throws IOException {
if (countingSumScorer == null) {
initCountingSumScorer();
}
return countingSumScorer.next();
}
public float score() throws IOException {
coordinator.initDoc();
float sum = countingSumScorer.score();
return sum * coordinator.coordFactor();
}
/**
* Skips to the first match beyond the current whose document number is
* greater than or equal to a given target.
*
* <p>
* When this method is used the {@link #explain(int)} method should not be
* used.
*
* @param target
* The target document number.
* @return true iff there is such a match.
*/
public boolean skipTo(int target) throws IOException {
if (countingSumScorer == null) {
initCountingSumScorer();
}
return countingSumScorer.skipTo(target);
}
/**
* Throws an UnsupportedOperationException. TODO: Implement an explanation
* of the coordination factor.
*
* @param doc
* The document number for the explanation.
* @throws UnsupportedOperationException
*/
public Explanation explain(int doc) {
throw new UnsupportedOperationException();
/*
* How to explain the coordination factor? initCountingSumScorer();
* return countingSumScorer.explain(doc); // misses coord factor.
*/
}
public int getMaxNumberOfDocs() {
return maxNumberOfDocs;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -