001: /*
002: * This program is free software; you can redistribute it and/or modify
003: * it under the terms of the GNU General Public License as published by
004: * the Free Software Foundation; either version 2 of the License, or
005: * (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU Library General Public License for more details.
011: *
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
015: */
016: package dlog4j.search;
017:
018: import java.io.IOException;
019: import java.util.BitSet;
020:
021: import org.apache.lucene.index.IndexReader;
022: import org.apache.lucene.index.Term;
023: import org.apache.lucene.index.TermDocs;
024:
025: /**
026: * A Filter that restricts search results to Documents that match a set of
027: * specified Field values.
028: *
029: * For example, suppose you create a search index to make your catalog of widgets
030: * searchable. When indexing, you add a field to each Document called "color"
031: * that has one of the following values: "blue", "green", "yellow", or "red".
032: * Now suppose that a user is executing a query but only wants to see green
033: * widgets in the results. The following code snippet yields that behavior:
034: * <pre>
035: * //In this example, we assume the Searcher and Query are already defined.
036: * //Define a FieldFilter to only show green colored widgets.
037: * Field myFilter = new FieldFilter("color", "green");
038: * Hits queryResults = mySearcher.execute(myQuery, myFilter);
039: * </pre>
040: *
041: * @author Matt Tucker (matt@coolservlets.com)
042: */
043: public class FieldFilter extends org.apache.lucene.search.Filter {
044:
045: private Term[] searchTerms;
046:
047: /**
048: * Creates a new field filter. The name of the field and the values to filter
049: * on are specified. In order for a Document to pass this filter, it must:
050: * <ol>
051: * <li>The given field must exist in the document.
052: * <li>The field value in the Document must exactly match one of the
053: * given values.</ol>
054: *
055: * @param field the name of the field to filter on.
056: * @param values the possible values of the field that search results must
057: * match.
058: */
059: public FieldFilter(String field, String[] values) {
060: searchTerms = new Term[values.length];
061: for (int i = 0; i < values.length; i++) {
062: searchTerms[i] = new Term(field, values[i]);
063: }
064: }
065:
066: /**
067: * Creates a new field filter. The name of the field and the value to filter
068: * on are specified. In order for a Document to pass this filter, it must:
069: * <ol>
070: * <li>The given field must exist in the document.
071: * <li>The field value in the Document must exactly match one of the
072: * given values.</ol>
073: *
074: * @param field the name of the field to filter on.
075: * @param value the value of the field that search results must match.
076: */
077: public FieldFilter(String field, String value) {
078: this (field, new String[] { value });
079: }
080:
081: public BitSet bits(IndexReader reader) throws IOException {
082: //Create a new BitSet with a capacity equal to the size of the index.
083: BitSet bits = new BitSet(reader.maxDoc());
084: //Match all search terms.
085: for (int i = 0; i < searchTerms.length; i++) {
086: //Get an enumeration of all the documents that match the specified
087: //field value.
088: TermDocs matchingDocs = reader.termDocs(searchTerms[i]);
089: try {
090: if (matchingDocs != null) {
091: while (matchingDocs.next()) {
092: bits.set(matchingDocs.doc());
093: }
094: }
095: } finally {
096: if (matchingDocs != null) {
097: matchingDocs.close();
098: }
099: }
100: }
101: return bits;
102: }
103: }
|