mirror of https://github.com/apache/lucene.git
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:
parent
732f9aeecc
commit
822068e56b
|
@ -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()
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue