LUCENE-5796: Fix Scorer getChildren for two combinations of BooleanQuery

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1608454 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2014-07-07 13:17:51 +00:00
parent b30059948e
commit 685a445a1b
5 changed files with 112 additions and 8 deletions

View File

@ -131,6 +131,11 @@ Optimizations
to another analyzer, e.g. per field name: PerFieldAnalyzerWrapper and
Solr's schema support. (Shay Banon, Uwe Schindler, Robert Muir)
Bug Fixes
* LUCENE-5796: Fixes the Scorer.getChildren() method for two combinations
of BooleanQuery. (Terry Smith via Robert Muir)
Test Framework
* LUCENE-5786: Unflushed/ truncated events file (hung testing subprocess).

View File

@ -18,6 +18,10 @@ package org.apache.lucene.search;
*/
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import org.apache.lucene.search.Scorer.ChildScorer;
/** Internal document-at-a-time scorers used to deal with stupid coord() computation */
class BooleanTopLevelScorers {
@ -39,6 +43,11 @@ class BooleanTopLevelScorers {
public float score() throws IOException {
return in.score() * boost;
}
@Override
public Collection<ChildScorer> getChildren() {
return Collections.singleton(new ChildScorer(in, "BOOSTED"));
}
}
/**

View File

@ -70,11 +70,6 @@ abstract class FilterScorer extends Scorer {
return in.cost();
}
@Override
public Collection<ChildScorer> getChildren() {
return in.getChildren();
}
@Override
public AttributeSource attributes() {
return in.attributes();

View File

@ -114,9 +114,9 @@ class MinShouldMatchSumScorer extends Scorer {
@Override
public final Collection<ChildScorer> getChildren() {
ArrayList<ChildScorer> children = new ArrayList<>(numScorers);
for (int i = 0; i < numScorers; i++) {
children.add(new ChildScorer(subScorers[i], "SHOULD"));
ArrayList<ChildScorer> children = new ArrayList<>(sortedSubScorers.length);
for (int i = 0; i < sortedSubScorers.length; i++) {
children.add(new ChildScorer(sortedSubScorers[i], "SHOULD"));
}
return children;
}

View File

@ -18,8 +18,10 @@ package org.apache.lucene.search;
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -33,6 +35,7 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.Scorer.ChildScorer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.LuceneTestCase;
@ -181,4 +184,96 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
}
}
public void testGetChildrenMinShouldMatchSumScorer() throws IOException {
final BooleanQuery query = new BooleanQuery();
query.add(new TermQuery(new Term(F2, "nutch")), Occur.SHOULD);
query.add(new TermQuery(new Term(F2, "web")), Occur.SHOULD);
query.add(new TermQuery(new Term(F2, "crawler")), Occur.SHOULD);
query.setMinimumNumberShouldMatch(2);
ScorerSummarizingCollector collector = new ScorerSummarizingCollector();
searcher.search(query, collector);
assertEquals(1, collector.getNumHits());
assertFalse(collector.getSummaries().isEmpty());
for (String summary : collector.getSummaries()) {
assertEquals(
"MinShouldMatchSumScorer\n" +
" SHOULD TermScorer body:nutch\n" +
" SHOULD TermScorer body:web\n" +
" SHOULD TermScorer body:crawler", summary);
}
}
public void testGetChildrenBoosterScorer() throws IOException {
final BooleanQuery query = new BooleanQuery();
query.add(new TermQuery(new Term(F2, "nutch")), Occur.SHOULD);
query.add(new TermQuery(new Term(F2, "miss")), Occur.SHOULD);
ScorerSummarizingCollector collector = new ScorerSummarizingCollector();
searcher.search(query, collector);
assertEquals(1, collector.getNumHits());
assertFalse(collector.getSummaries().isEmpty());
for (String summary : collector.getSummaries()) {
assertEquals(
"BoostedScorer\n" +
" BOOSTED TermScorer body:nutch", summary);
}
}
private static class ScorerSummarizingCollector implements Collector {
private final List<String> summaries = new ArrayList<>();
private int numHits[] = new int[1];
public int getNumHits() {
return numHits[0];
}
public List<String> getSummaries() {
return summaries;
}
@Override
public LeafCollector getLeafCollector(AtomicReaderContext context) throws IOException {
return new LeafCollector() {
@Override
public void setScorer(Scorer scorer) throws IOException {
final StringBuilder builder = new StringBuilder();
summarizeScorer(builder, scorer, 0);
summaries.add(builder.toString());
}
@Override
public void collect(int doc) throws IOException {
numHits[0]++;
}
@Override
public boolean acceptsDocsOutOfOrder() {
return false;
}
};
}
private static void summarizeScorer(final StringBuilder builder, final Scorer scorer, final int indent) {
builder.append(scorer.getClass().getSimpleName());
if (scorer instanceof TermScorer) {
TermQuery termQuery = (TermQuery) scorer.getWeight().getQuery();
builder.append(" ").append(termQuery.getTerm().field()).append(":").append(termQuery.getTerm().text());
}
for (final ChildScorer childScorer : scorer.getChildren()) {
indent(builder, indent + 1).append(childScorer.relationship).append(" ");
summarizeScorer(builder, childScorer.child, indent + 2);
}
}
private static StringBuilder indent(final StringBuilder builder, final int indent) {
if (builder.length() != 0) {
builder.append("\n");
}
for (int i = 0; i < indent; i++) {
builder.append(" ");
}
return builder;
}
}
}