Code with Finding: |
class BooleanQuery.BooleanWeight {
public Explanation explain(IndexReader reader, int doc)
throws IOException {
final int minShouldMatch =
BooleanQuery.this.getMinimumNumberShouldMatch();
ComplexExplanation sumExpl = new ComplexExplanation();
sumExpl.setDescription("sum of:");
int coord = 0;
int maxCoord = 0;
float sum = 0.0f;
boolean fail = false;
int shouldMatchCount = 0;
for (Iterator wIter = weights.iterator(), cIter = clauses.iterator(); wIter.hasNext();) {
Weight w = (Weight) wIter.next();
BooleanClause c = (BooleanClause) cIter.next();
if (w.scorer(reader, true, true) == null) {
continue;
}
Explanation e = w.explain(reader, doc);
if (!c.isProhibited()) maxCoord++;
if (e.isMatch()) {
if (!c.isProhibited()) {
sumExpl.addDetail(e);
sum += e.getValue();
coord++;
} else {
Explanation r =
new Explanation(0.0f, "match on prohibited clause (" + c.getQuery().toString() + ")");
r.addDetail(e);
sumExpl.addDetail(r);
fail = true;
}
if (c.getOccur() == Occur.SHOULD)
shouldMatchCount++;
} else if (c.isRequired()) {
Explanation r = new Explanation(0.0f, "no match on required clause (" + c.getQuery().toString() + ")");
r.addDetail(e);
sumExpl.addDetail(r);
fail = true;
}
}
if (fail) {
sumExpl.setMatch(Boolean.FALSE);
sumExpl.setValue(0.0f);
sumExpl.setDescription
("Failure to meet condition(s) of required/prohibited clause(s)");
return sumExpl;
} else if (shouldMatchCount < minShouldMatch) {
sumExpl.setMatch(Boolean.FALSE);
sumExpl.setValue(0.0f);
sumExpl.setDescription("Failure to match minimum number "+
"of optional clauses: " + minShouldMatch);
return sumExpl;
}
sumExpl.setMatch(0 < coord ? Boolean.TRUE : Boolean.FALSE);
sumExpl.setValue(sum);
float coordFactor = similarity.coord(coord, maxCoord);
if (coordFactor == 1.0f) // coord is no-op
return sumExpl; // eliminate wrapper
else {
ComplexExplanation result = new ComplexExplanation(sumExpl.isMatch(),
sum*coordFactor,
"product of:");
result.addDetail(sumExpl);
result.addDetail(new Explanation(coordFactor,
"coord("+coord+"/"+maxCoord+")"));
return result;
}
}
}
class BooleanQuery.BooleanWeight {
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer)
throws IOException {
List required = new ArrayList();
List prohibited = new ArrayList();
List optional = new ArrayList();
for (Iterator wIter = weights.iterator(), cIter = clauses.iterator(); wIter.hasNext();) {
Weight w = (Weight) wIter.next();
BooleanClause c = (BooleanClause) cIter.next();
Scorer subScorer = w.scorer(reader, true, false);
if (subScorer == null) {
if (c.isRequired()) {
return null;
}
} else if (c.isRequired()) {
required.add(subScorer);
} else if (c.isProhibited()) {
prohibited.add(subScorer);
} else {
optional.add(subScorer);
}
}
// Check if we can return a BooleanScorer
scoreDocsInOrder |= !allowDocsOutOfOrder; // until it is removed, factor in the static setting.
if (!scoreDocsInOrder && topScorer && required.size() == 0 && prohibited.size() < 32) {
return new BooleanScorer(similarity, minNrShouldMatch, optional, prohibited);
}
if (required.size() == 0 && optional.size() == 0) {
// no required and optional clauses.
return null;
} else if (optional.size() < minNrShouldMatch) {
// either >1 req scorer, or there are 0 req scorers and at least 1
// optional scorer. Therefore if there are not enough optional scorers
// no documents will be matched by the query
return null;
}
// Return a BooleanScorer2
return new BooleanScorer2(similarity, minNrShouldMatch, required, prohibited, optional);
}
}
|