tjones 2004/04/21 12:18:44 Added: src/java/org/apache/lucene/search FilteredQuery.java src/test/org/apache/lucene/search TestFilteredQuery.java Log: new Query which applies a Filter to another Query Revision Changes Path 1.1 jakarta-lucene/src/java/org/apache/lucene/search/FilteredQuery.java Index: FilteredQuery.java =================================================================== package org.apache.lucene.search; /** * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.apache.lucene.index.IndexReader; import java.io.IOException; import java.util.BitSet; /** * A query that applies a filter to the results of another query. * * <p>Note: the bits are retrieved from the filter each time this * query is used in a search - use a CachingWrapperFilter to avoid * regenerating the bits every time. * * <p>Created: Apr 20, 2004 8:58:29 AM * * @author Tim Jones * @since 1.4 * @version $Id: FilteredQuery.java,v 1.1 2004/04/21 19:18:44 tjones Exp $ * @see CachingWrapperFilter */ public class FilteredQuery extends Query { Query query; Filter filter; /** * Constructs a new query which applies a filter to the results of the original query. * Filter.bits() will be called every time this query is used in a search. * @param query Query to be filtered, cannot be <code>null</code>. * @param filter Filter to apply to query results, cannot be <code>null</code>. */ public FilteredQuery (Query query, Filter filter) { this.query = query; this.filter = filter; } /** * Returns a Weight that applies the filter to the enclosed query's Weight. * This is accomplished by overriding the Scorer returned by the Weight. */ protected Weight createWeight (final Searcher searcher) { final Weight weight = query.createWeight (searcher); return new Weight() { // pass these methods through to enclosed query's weight public float getValue() { return weight.getValue(); } public float sumOfSquaredWeights() throws IOException { return weight.sumOfSquaredWeights(); } public void normalize (float v) { weight.normalize(v); } public Explanation explain (IndexReader ir, int i) throws IOException { return weight.explain (ir, i); } // return this query public Query getQuery() { return FilteredQuery.this; } // return a scorer that overrides the enclosed query's score if // the given hit has been filtered out. public Scorer scorer (IndexReader indexReader) throws IOException { final Scorer scorer = weight.scorer (indexReader); final BitSet bitset = filter.bits (indexReader); return new Scorer (query.getSimilarity (searcher)) { // pass these methods through to the enclosed scorer public boolean next() throws IOException { return scorer.next(); } public int doc() { return scorer.doc(); } public boolean skipTo (int i) throws IOException { return scorer.skipTo(i); } // if the document has been filtered out, set score to 0.0 public float score() throws IOException { return (bitset.get(scorer.doc())) ? scorer.score() : 0.0f; } // add an explanation about whether the document was filtered public Explanation explain (int i) throws IOException { Explanation exp = scorer.explain (i); if (bitset.get(i)) exp.setDescription ("allowed by filter: "+exp.getDescription()); else exp.setDescription ("removed by filter: "+exp.getDescription()); return exp; } }; } }; } /** Prints a user-readable version of this query. */ public String toString (String s) { return "filtered("+query.toString()+")"; } /** Returns true iff <code>o</code> is equal to this. */ public boolean equals(Object o) { if (o instanceof FilteredQuery) { FilteredQuery fq = (FilteredQuery) o; return (query.equals(fq.query) && filter.equals(fq.filter)); } return false; } /** Returns a hash code value for this object. */ public int hashCode() { return query.hashCode() ^ filter.hashCode(); } } 1.1 jakarta-lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java Index: TestFilteredQuery.java =================================================================== package org.apache.lucene.search; /** * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import junit.framework.TestCase; import org.apache.lucene.analysis.WhitespaceAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.store.RAMDirectory; import java.util.BitSet; import java.io.IOException; /** * FilteredQuery JUnit tests. * * <p>Created: Apr 21, 2004 1:21:46 PM * * @author Tim Jones * @version $Id: TestFilteredQuery.java,v 1.1 2004/04/21 19:18:44 tjones Exp $ * @since 1.4 */ public class TestFilteredQuery extends TestCase { private IndexSearcher searcher; private RAMDirectory directory; private Query query; private Filter filter; public void setUp() throws Exception { directory = new RAMDirectory(); IndexWriter writer = new IndexWriter (directory, new WhitespaceAnalyzer(), true); Document doc = new Document(); doc.add (Field.Text ("field", "one two three four five")); doc.add (Field.Text ("sorter", "b")); writer.addDocument (doc); doc = new Document(); doc.add (Field.Text ("field", "one two three four")); doc.add (Field.Text ("sorter", "d")); writer.addDocument (doc); doc = new Document(); doc.add (Field.Text ("field", "one two three y")); doc.add (Field.Text ("sorter", "a")); writer.addDocument (doc); doc = new Document(); doc.add (Field.Text ("field", "one two x")); doc.add (Field.Text ("sorter", "c")); writer.addDocument (doc); writer.optimize (); writer.close (); searcher = new IndexSearcher (directory); query = new TermQuery (new Term ("field", "three")); filter = new Filter() { public BitSet bits (IndexReader reader) throws IOException { BitSet bitset = new BitSet(5); bitset.set (1); bitset.set (3); return bitset; } }; } public void tearDown() throws Exception { searcher.close(); directory.close(); } public void testFilteredQuery() throws Exception { Query filteredquery = new FilteredQuery (query, filter); Hits hits = searcher.search (filteredquery); assertEquals (hits.length(), 1); assertEquals (hits.id(0), 1); hits = searcher.search (filteredquery, new Sort("sorter")); assertEquals (hits.length(), 1); assertEquals (hits.id(0), 1); filteredquery = new FilteredQuery (new TermQuery (new Term ("field", "one")), filter); hits = searcher.search (filteredquery); assertEquals (hits.length(), 2); filteredquery = new FilteredQuery (new TermQuery (new Term ("field", "x")), filter); hits = searcher.search (filteredquery); assertEquals (hits.length(), 1); assertEquals (hits.id(0), 3); filteredquery = new FilteredQuery (new TermQuery (new Term ("field", "y")), filter); hits = searcher.search (filteredquery); assertEquals (hits.length(), 0); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]