LUCENE-6290: Make the filter -> query migration less trappy.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1662203 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrien Grand 2015-02-25 12:07:58 +00:00
parent 732f9aeecc
commit 822068e56b
6 changed files with 113 additions and 4 deletions

View File

@ -108,6 +108,10 @@ Optimizations
in order to advance doc IDs, which takes advantage of the cost() API. in order to advance doc IDs, which takes advantage of the cost() API.
(Adrien Grand) (Adrien Grand)
* LUCENE-6290: QueryWrapperFilter propagates approximations and FilteredQuery
rewrites to a BooleanQuery when the filter is a QueryWrapperFilter in order
to leverage approximations. (Adrien Grand)
API Changes API Changes
* LUCENE-6204, LUCENE-6208: Simplify CompoundFormat: remove files() * LUCENE-6204, LUCENE-6208: Simplify CompoundFormat: remove files()

View File

@ -25,6 +25,7 @@ import java.util.Set;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.util.Bits; import org.apache.lucene.util.Bits;
import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.ToStringUtils;
@ -301,6 +302,16 @@ public class FilteredQuery extends Query {
* it returns a new {@code FilteredQuery} wrapping the rewritten query. */ * it returns a new {@code FilteredQuery} wrapping the rewritten query. */
@Override @Override
public Query rewrite(IndexReader reader) throws IOException { public Query rewrite(IndexReader reader) throws IOException {
if (filter instanceof QueryWrapperFilter) {
// In that case the filter does not implement random-access anyway so
// we want to take advantage of approximations
BooleanQuery rewritten = new BooleanQuery();
rewritten.add(query, Occur.MUST);
rewritten.add(((QueryWrapperFilter) filter).getQuery(), Occur.FILTER);
rewritten.setBoost(getBoost());
return rewritten;
}
final Query queryRewritten = query.rewrite(reader); final Query queryRewritten = query.rewrite(reader);
if (queryRewritten != query) { if (queryRewritten != query) {

View File

@ -17,12 +17,12 @@ package org.apache.lucene.search;
* limitations under the License. * limitations under the License.
*/ */
import org.apache.lucene.index.PostingsEnum; import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.util.Bits; import org.apache.lucene.util.Bits;
import java.io.IOException;
/** /**
* Constrains search results to only match those which also match a provided * Constrains search results to only match those which also match a provided
* query. * query.
@ -44,6 +44,13 @@ public class QueryWrapperFilter extends Filter {
this.query = query; this.query = query;
} }
@Override
public Query rewrite(IndexReader reader) throws IOException {
ConstantScoreQuery rewritten = new ConstantScoreQuery(query);
rewritten.setBoost(0);
return rewritten;
}
/** returns the inner Query */ /** returns the inner Query */
public final Query getQuery() { public final Query getQuery() {
return query; return query;

View File

@ -25,6 +25,8 @@ import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.SortedDocValuesField; import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum; import org.apache.lucene.index.PostingsEnum;
@ -587,6 +589,51 @@ public class TestFilteredQuery extends LuceneTestCase {
assertEquals(totalDocsWithZero, search.totalHits); assertEquals(totalDocsWithZero, search.totalHits);
IOUtils.close(reader, directory); IOUtils.close(reader, directory);
} }
public void testPreservesScores() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
Document doc = new Document();
doc.add(new StringField("foo", "bar", Store.NO));
writer.addDocument(doc);
writer.commit();
final IndexReader reader = writer.getReader();
writer.close();
final IndexSearcher searcher = new IndexSearcher(reader);
final Query query = new TermQuery(new Term("foo", "bar"));
query.setBoost(random().nextFloat());
FilteredQuery fq = new FilteredQuery(query, new Filter() {
@Override
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs)
throws IOException {
return new DocIdSet() {
@Override
public long ramBytesUsed() {
return 0;
}
@Override
public DocIdSetIterator iterator() throws IOException {
return DocIdSetIterator.all(context.reader().maxDoc());
}
};
}
@Override
public String toString(String field) {
return "dummy";
}
});
assertEquals(searcher.search(query, 1).scoreDocs[0].score, searcher.search(fq, 1).scoreDocs[0].score, 0f);
fq.setBoost(random().nextFloat());
// QueryWrapperFilter has special rewrite rules
FilteredQuery fq2 = new FilteredQuery(query, new QueryWrapperFilter(new MatchAllDocsQuery()));
fq2.setBoost(fq.getBoost());
fq2.setBoost(42);
assertEquals(searcher.search(fq, 1).scoreDocs[0].score, searcher.search(fq2, 1).scoreDocs[0].score, 10e-5);
reader.close();
dir.close();
}
} }

View File

@ -16,11 +16,14 @@ package org.apache.lucene.search;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
@ -148,4 +151,40 @@ public class TestQueryWrapperFilter extends LuceneTestCase {
reader.close(); reader.close();
dir.close(); dir.close();
} }
public void testScore() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
Document doc = new Document();
doc.add(new StringField("foo", "bar", Store.NO));
writer.addDocument(doc);
writer.commit();
final IndexReader reader = writer.getReader();
writer.close();
final IndexSearcher searcher = new IndexSearcher(reader);
final Query query = new QueryWrapperFilter(new TermQuery(new Term("foo", "bar")));
final TopDocs topDocs = searcher.search(query, 1);
assertEquals(1, topDocs.totalHits);
assertEquals(0f, topDocs.scoreDocs[0].score, 0f);
reader.close();
dir.close();
}
public void testQueryWrapperFilterPropagatesApproximations() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
Document doc = new Document();
doc.add(new StringField("foo", "bar", Store.NO));
writer.addDocument(doc);
writer.commit();
final IndexReader reader = writer.getReader();
writer.close();
final IndexSearcher searcher = new IndexSearcher(reader);
final Query query = new QueryWrapperFilter(new RandomApproximationQuery(new TermQuery(new Term("foo", "bar")), random()));
final Weight weight = searcher.createNormalizedWeight(query, random().nextBoolean());
final Scorer scorer = weight.scorer(reader.leaves().get(0), null);
assertNotNull(scorer.asTwoPhaseIterator());
reader.close();
dir.close();
}
} }

View File

@ -30,6 +30,7 @@ import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.CachingWrapperFilter;
import org.apache.lucene.search.Filter; import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FilteredQuery; import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
@ -119,7 +120,7 @@ public class TestBlockJoinValidation extends LuceneTestCase {
Query parentQueryWithRandomChild = createParentQuery(); Query parentQueryWithRandomChild = createParentQuery();
ToChildBlockJoinQuery blockJoinQuery = new ToChildBlockJoinQuery(parentQueryWithRandomChild, parentsFilter); ToChildBlockJoinQuery blockJoinQuery = new ToChildBlockJoinQuery(parentQueryWithRandomChild, parentsFilter);
Filter childFilter = new QueryWrapperFilter(new TermQuery(new Term("common_field", "1"))); Filter childFilter = new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("common_field", "1"))));
thrown.expect(IllegalStateException.class); thrown.expect(IllegalStateException.class);
thrown.expectMessage(ToChildBlockJoinQuery.ILLEGAL_ADVANCE_ON_PARENT); thrown.expectMessage(ToChildBlockJoinQuery.ILLEGAL_ADVANCE_ON_PARENT);
indexSearcher.search(new FilteredQuery(blockJoinQuery, childFilter), 1); indexSearcher.search(new FilteredQuery(blockJoinQuery, childFilter), 1);