001: package org.apache.lucene.search;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import org.apache.lucene.document.Document;
021: import org.apache.lucene.document.FieldSelector;
022: import org.apache.lucene.index.CorruptIndexException;
023: import org.apache.lucene.index.IndexReader;
024: import org.apache.lucene.index.Term;
025: import org.apache.lucene.store.Directory;
026:
027: import java.io.IOException;
028: import java.util.BitSet;
029:
030: /** Implements search over a single IndexReader.
031: *
032: * <p>Applications usually need only call the inherited {@link #search(Query)}
033: * or {@link #search(Query,Filter)} methods. For performance reasons it is
034: * recommended to open only one IndexSearcher and use it for all of your searches.
035: *
036: * <p>Note that you can only access Hits from an IndexSearcher as long as it is
037: * not yet closed, otherwise an IOException will be thrown.
038: */
039: public class IndexSearcher extends Searcher {
040: IndexReader reader;
041: private boolean closeReader;
042:
043: /** Creates a searcher searching the index in the named directory.
044: * @throws CorruptIndexException if the index is corrupt
045: * @throws IOException if there is a low-level IO error
046: */
047: public IndexSearcher(String path) throws CorruptIndexException,
048: IOException {
049: this (IndexReader.open(path), true);
050: }
051:
052: /** Creates a searcher searching the index in the provided directory.
053: * @throws CorruptIndexException if the index is corrupt
054: * @throws IOException if there is a low-level IO error
055: */
056: public IndexSearcher(Directory directory)
057: throws CorruptIndexException, IOException {
058: this (IndexReader.open(directory), true);
059: }
060:
061: /** Creates a searcher searching the provided index. */
062: public IndexSearcher(IndexReader r) {
063: this (r, false);
064: }
065:
066: private IndexSearcher(IndexReader r, boolean closeReader) {
067: reader = r;
068: this .closeReader = closeReader;
069: }
070:
071: /** Return the {@link IndexReader} this searches. */
072: public IndexReader getIndexReader() {
073: return reader;
074: }
075:
076: /**
077: * Note that the underlying IndexReader is not closed, if
078: * IndexSearcher was constructed with IndexSearcher(IndexReader r).
079: * If the IndexReader was supplied implicitly by specifying a directory, then
080: * the IndexReader gets closed.
081: */
082: public void close() throws IOException {
083: if (closeReader)
084: reader.close();
085: }
086:
087: // inherit javadoc
088: public int docFreq(Term term) throws IOException {
089: return reader.docFreq(term);
090: }
091:
092: // inherit javadoc
093: public Document doc(int i) throws CorruptIndexException,
094: IOException {
095: return reader.document(i);
096: }
097:
098: // inherit javadoc
099: public Document doc(int i, FieldSelector fieldSelector)
100: throws CorruptIndexException, IOException {
101: return reader.document(i, fieldSelector);
102: }
103:
104: // inherit javadoc
105: public int maxDoc() throws IOException {
106: return reader.maxDoc();
107: }
108:
109: // inherit javadoc
110: public TopDocs search(Weight weight, Filter filter, final int nDocs)
111: throws IOException {
112:
113: if (nDocs <= 0) // null might be returned from hq.top() below.
114: throw new IllegalArgumentException("nDocs must be > 0");
115:
116: TopDocCollector collector = new TopDocCollector(nDocs);
117: search(weight, filter, collector);
118: return collector.topDocs();
119: }
120:
121: // inherit javadoc
122: public TopFieldDocs search(Weight weight, Filter filter,
123: final int nDocs, Sort sort) throws IOException {
124:
125: TopFieldDocCollector collector = new TopFieldDocCollector(
126: reader, sort, nDocs);
127: search(weight, filter, collector);
128: return (TopFieldDocs) collector.topDocs();
129: }
130:
131: // inherit javadoc
132: public void search(Weight weight, Filter filter,
133: final HitCollector results) throws IOException {
134: HitCollector collector = results;
135: if (filter != null) {
136: final BitSet bits = filter.bits(reader);
137: collector = new HitCollector() {
138: public final void collect(int doc, float score) {
139: if (bits.get(doc)) { // skip docs not in bits
140: results.collect(doc, score);
141: }
142: }
143: };
144: }
145:
146: Scorer scorer = weight.scorer(reader);
147: if (scorer == null)
148: return;
149: scorer.score(collector);
150: }
151:
152: public Query rewrite(Query original) throws IOException {
153: Query query = original;
154: for (Query rewrittenQuery = query.rewrite(reader); rewrittenQuery != query; rewrittenQuery = query
155: .rewrite(reader)) {
156: query = rewrittenQuery;
157: }
158: return query;
159: }
160:
161: public Explanation explain(Weight weight, int doc)
162: throws IOException {
163: return weight.explain(reader, doc);
164: }
165: }
|