Revert "LUCENE-7628: Scorer.getChildren() returns only matching Scorers"

This reverts commit 5bdc492c9c.
This commit is contained in:
Alan Woodward 2017-01-23 11:29:21 +00:00
parent d34f549df6
commit 94e3460305
9 changed files with 33 additions and 82 deletions

View File

@ -77,11 +77,6 @@ API Changes
* LUCENE-7643: Replaced doc-values queries in lucene/sandbox with factory * LUCENE-7643: Replaced doc-values queries in lucene/sandbox with factory
methods on the *DocValuesField classes. (Adrien Grand) methods on the *DocValuesField classes. (Adrien Grand)
* LUCENE-7628: Scorer.getChildren() now only returns Scorers that are
positioned on the current document, and can throw an IOException.
AssertingScorer checks that getChildren() is not called on an unpositioned
Scorer. (Alan Woodward, Adrien Grand)
New Features New Features
* LUCENE-7623: Add FunctionScoreQuery and FunctionMatchQuery (Alan Woodward, * LUCENE-7623: Add FunctionScoreQuery and FunctionMatchQuery (Alan Woodward,

View File

@ -194,9 +194,9 @@ abstract class DisjunctionScorer extends Scorer {
protected abstract float score(DisiWrapper topList) throws IOException; protected abstract float score(DisiWrapper topList) throws IOException;
@Override @Override
public final Collection<ChildScorer> getChildren() throws IOException { public final Collection<ChildScorer> getChildren() {
ArrayList<ChildScorer> children = new ArrayList<>(); ArrayList<ChildScorer> children = new ArrayList<>();
for (DisiWrapper scorer = getSubMatches(); scorer != null; scorer = scorer.next) { for (DisiWrapper scorer : subScorers) {
children.add(new ChildScorer(scorer.scorer, "SHOULD")); children.add(new ChildScorer(scorer.scorer, "SHOULD"));
} }
return children; return children;

View File

@ -20,6 +20,7 @@ package org.apache.lucene.search;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.LongStream; import java.util.stream.LongStream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@ -89,6 +90,7 @@ final class MinShouldMatchSumScorer extends Scorer {
final DisiWrapper[] tail; final DisiWrapper[] tail;
int tailSize; int tailSize;
final Collection<ChildScorer> childScorers;
final long cost; final long cost;
MinShouldMatchSumScorer(Weight weight, Collection<Scorer> scorers, int minShouldMatch) { MinShouldMatchSumScorer(Weight weight, Collection<Scorer> scorers, int minShouldMatch) {
@ -113,17 +115,17 @@ final class MinShouldMatchSumScorer extends Scorer {
addLead(new DisiWrapper(scorer)); addLead(new DisiWrapper(scorer));
} }
List<ChildScorer> children = new ArrayList<>();
for (Scorer scorer : scorers) {
children.add(new ChildScorer(scorer, "SHOULD"));
}
this.childScorers = Collections.unmodifiableCollection(children);
this.cost = cost(scorers.stream().map(Scorer::iterator).mapToLong(DocIdSetIterator::cost), scorers.size(), minShouldMatch); this.cost = cost(scorers.stream().map(Scorer::iterator).mapToLong(DocIdSetIterator::cost), scorers.size(), minShouldMatch);
} }
@Override @Override
public final Collection<ChildScorer> getChildren() throws IOException { public final Collection<ChildScorer> getChildren() {
List<ChildScorer> matchingScorers = new ArrayList<>(); return childScorers;
updateFreq();
for (DisiWrapper s = lead; s != null; s = s.next) {
matchingScorers.add(new ChildScorer(s.scorer, "SHOULD"));
}
return matchingScorers;
} }
@Override @Override

View File

@ -77,17 +77,9 @@ public abstract class Scorer {
return weight; return weight;
} }
/** /** Returns child sub-scorers
* Returns child sub-scorers positioned on the current document * @lucene.experimental */
* public Collection<ChildScorer> getChildren() {
* Note that this method should not be called on Scorers passed to {@link LeafCollector#setScorer(Scorer)},
* as these may be synthetic Scorers produced by {@link BulkScorer} which will throw an Exception.
*
* This method should only be called when the Scorer is positioned
*
* @lucene.experimental
*/
public Collection<ChildScorer> getChildren() throws IOException {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -169,7 +169,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
}; };
} }
private void fillLeaves(Scorer scorer, Set<Scorer> set) throws IOException { private void fillLeaves(Scorer scorer, Set<Scorer> set) {
if (scorer.getWeight().getQuery() instanceof TermQuery) { if (scorer.getWeight().getQuery() instanceof TermQuery) {
set.add(scorer); set.add(scorer);
} else { } else {
@ -186,40 +186,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
public int freq(int doc) throws IOException { public int freq(int doc) throws IOException {
return docCounts.get(doc); return docCounts.get(doc);
} }
}
public void testDisjunctionMatches() throws IOException {
BooleanQuery.Builder bq1 = new BooleanQuery.Builder();
bq1.add(new TermQuery(new Term(F1, "lucene")), Occur.SHOULD);
bq1.add(new PhraseQuery(F2, "search", "engine"), Occur.SHOULD);
Weight w1 = scorerSearcher.createNormalizedWeight(bq1.build(), true);
Scorer s1 = w1.scorer(reader.leaves().get(0));
assertEquals(0, s1.iterator().nextDoc());
assertEquals(2, s1.getChildren().size());
BooleanQuery.Builder bq2 = new BooleanQuery.Builder();
bq2.add(new TermQuery(new Term(F1, "lucene")), Occur.SHOULD);
bq2.add(new PhraseQuery(F2, "search", "library"), Occur.SHOULD);
Weight w2 = scorerSearcher.createNormalizedWeight(bq2.build(), true);
Scorer s2 = w2.scorer(reader.leaves().get(0));
assertEquals(0, s2.iterator().nextDoc());
assertEquals(1, s2.getChildren().size());
}
public void testMinShouldMatchMatches() throws IOException {
BooleanQuery.Builder bq = new BooleanQuery.Builder();
bq.add(new TermQuery(new Term(F1, "lucene")), Occur.SHOULD);
bq.add(new TermQuery(new Term(F2, "lucene")), Occur.SHOULD);
bq.add(new PhraseQuery(F2, "search", "library"), Occur.SHOULD);
bq.setMinimumNumberShouldMatch(2);
Weight w = scorerSearcher.createNormalizedWeight(bq.build(), true);
Scorer s = w.scorer(reader.leaves().get(0));
assertEquals(0, s.iterator().nextDoc());
assertEquals(2, s.getChildren().size());
} }
public void testGetChildrenMinShouldMatchSumScorer() throws IOException { public void testGetChildrenMinShouldMatchSumScorer() throws IOException {
@ -236,12 +203,12 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
for (String summary : collector.getSummaries()) { for (String summary : collector.getSummaries()) {
assertEquals( assertEquals(
"ConjunctionScorer\n" + "ConjunctionScorer\n" +
" MUST ConstantScoreScorer\n" + " MUST ConstantScoreScorer\n" +
" MUST MinShouldMatchSumScorer\n" + " MUST MinShouldMatchSumScorer\n" +
" SHOULD TermScorer body:web\n" + " SHOULD TermScorer body:nutch\n" +
" SHOULD TermScorer body:crawler\n" + " SHOULD TermScorer body:crawler\n" +
" SHOULD TermScorer body:nutch", " SHOULD TermScorer body:web",
summary); summary);
} }
} }
@ -294,7 +261,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
}; };
} }
private static void summarizeScorer(final StringBuilder builder, final Scorer scorer, final int indent) throws IOException { private static void summarizeScorer(final StringBuilder builder, final Scorer scorer, final int indent) {
builder.append(scorer.getClass().getSimpleName()); builder.append(scorer.getClass().getSimpleName());
if (scorer instanceof TermScorer) { if (scorer instanceof TermScorer) {
TermQuery termQuery = (TermQuery) scorer.getWeight().getQuery(); TermQuery termQuery = (TermQuery) scorer.getWeight().getQuery();

View File

@ -68,6 +68,7 @@ public class TestSubScorerFreqs extends LuceneTestCase {
private static class CountingCollector extends FilterCollector { private static class CountingCollector extends FilterCollector {
public final Map<Integer, Map<Query, Float>> docCounts = new HashMap<>(); public final Map<Integer, Map<Query, Float>> docCounts = new HashMap<>();
private final Map<Query, Scorer> subScorers = new HashMap<>();
private final Set<String> relationships; private final Set<String> relationships;
public CountingCollector(Collector other) { public CountingCollector(Collector other) {
@ -78,29 +79,24 @@ public class TestSubScorerFreqs extends LuceneTestCase {
super(other); super(other);
this.relationships = relationships; this.relationships = relationships;
} }
private Map<Query, Scorer> getSubScorers(Scorer scorer) throws IOException { public void setSubScorers(Scorer scorer, String relationship) {
Map<Query, Scorer> collected = new HashMap<>();
for (ChildScorer child : scorer.getChildren()) { for (ChildScorer child : scorer.getChildren()) {
if (scorer instanceof AssertingScorer || relationships.contains(child.relationship)) { if (scorer instanceof AssertingScorer || relationships.contains(child.relationship)) {
collected.put(scorer.getWeight().getQuery(), scorer); setSubScorers(child.child, child.relationship);
} }
collected.putAll(getSubScorers(child.child));
} }
return collected; subScorers.put(scorer.getWeight().getQuery(), scorer);
} }
public LeafCollector getLeafCollector(LeafReaderContext context) public LeafCollector getLeafCollector(LeafReaderContext context)
throws IOException { throws IOException {
final int docBase = context.docBase; final int docBase = context.docBase;
return new FilterLeafCollector(super.getLeafCollector(context)) { return new FilterLeafCollector(super.getLeafCollector(context)) {
Scorer scorer;
@Override @Override
public void collect(int doc) throws IOException { public void collect(int doc) throws IOException {
final Map<Query, Float> freqs = new HashMap<Query, Float>(); final Map<Query, Float> freqs = new HashMap<Query, Float>();
final Map<Query, Scorer> subScorers = getSubScorers(scorer);
for (Map.Entry<Query, Scorer> ent : subScorers.entrySet()) { for (Map.Entry<Query, Scorer> ent : subScorers.entrySet()) {
Scorer value = ent.getValue(); Scorer value = ent.getValue();
int matchId = value.docID(); int matchId = value.docID();
@ -113,7 +109,8 @@ public class TestSubScorerFreqs extends LuceneTestCase {
@Override @Override
public void setScorer(Scorer scorer) throws IOException { public void setScorer(Scorer scorer) throws IOException {
super.setScorer(scorer); super.setScorer(scorer);
this.scorer = scorer; subScorers.clear();
setSubScorers(scorer, "TOP");
} }
}; };

View File

@ -16,7 +16,6 @@
*/ */
package org.apache.lucene.facet; package org.apache.lucene.facet;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -33,7 +32,7 @@ class AssertingSubDocsAtOnceCollector extends SimpleCollector {
List<Scorer> allScorers; List<Scorer> allScorers;
@Override @Override
public void setScorer(Scorer s) throws IOException { public void setScorer(Scorer s) {
// Gathers all scorers, including s and "under": // Gathers all scorers, including s and "under":
allScorers = new ArrayList<>(); allScorers = new ArrayList<>();
allScorers.add(s); allScorers.add(s);

View File

@ -78,7 +78,6 @@ public class AssertingScorer extends Scorer {
// collectors (e.g. ToParentBlockJoinCollector) that // collectors (e.g. ToParentBlockJoinCollector) that
// need to walk the scorer tree will miss/skip the // need to walk the scorer tree will miss/skip the
// Scorer we wrap: // Scorer we wrap:
assert iterating();
return Collections.singletonList(new ChildScorer(in, "SHOULD")); return Collections.singletonList(new ChildScorer(in, "SHOULD"));
} }

View File

@ -502,7 +502,7 @@ public class LTRScoringQuery extends Query {
} }
@Override @Override
public Collection<ChildScorer> getChildren() throws IOException { public Collection<ChildScorer> getChildren() {
return featureTraversalScorer.getChildren(); return featureTraversalScorer.getChildren();
} }