KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > data > search > LuceneSearcher


1 package prefuse.data.search;
2
3 import java.io.IOException JavaDoc;
4 import java.util.HashMap JavaDoc;
5
6 import org.apache.lucene.analysis.Analyzer;
7 import org.apache.lucene.analysis.standard.StandardAnalyzer;
8 import org.apache.lucene.document.Document;
9 import org.apache.lucene.index.IndexReader;
10 import org.apache.lucene.index.IndexWriter;
11 import org.apache.lucene.queryParser.MultiFieldQueryParser;
12 import org.apache.lucene.queryParser.ParseException;
13 import org.apache.lucene.queryParser.QueryParser;
14 import org.apache.lucene.search.Hits;
15 import org.apache.lucene.search.IndexSearcher;
16 import org.apache.lucene.search.Query;
17 import org.apache.lucene.search.Searcher;
18 import org.apache.lucene.store.Directory;
19 import org.apache.lucene.store.RAMDirectory;
20
21 /**
22  * Adapter class for interfacing with the Lucene search engine. By default,
23  * instances of this class use an in-memory search index for English language
24  * text, for use within a single application session. The class can, however,
25  * be parameterized for any number of other configurations, including accessing
26  * persistent search indices.
27  *
28  * @version 1.0
29  * @author <a HREF="http://jheer.org">jeffrey heer</a>
30  */

31 public class LuceneSearcher {
32
33     /** Default Document field used to index text. */
34     public static final String JavaDoc FIELD = "prefuse-text";
35     /** Document field used to store the document ID number. */
36     public static final String JavaDoc ID = "prefuse-id";
37     
38     private Directory directory;
39     private Analyzer analyzer;
40     private String JavaDoc[] fields;
41     
42     private Searcher searcher;
43     private IndexReader reader;
44     private IndexWriter writer;
45     private boolean m_readMode = true;
46     private boolean m_readOnly = false;
47     
48     private HashMap JavaDoc m_hitCountCache;
49         
50     /**
51      * Create a new LuceneSearcher using an in-memory search index.
52      */

53     public LuceneSearcher() {
54         this(new RAMDirectory(), FIELD, false);
55     }
56     
57     /**
58      * Create a new LuceneSearcher using the specified search index location.
59      * @param dir the Lucene Directory indicating the search index to use.
60      */

61     public LuceneSearcher(Directory dir) {
62         this(dir, FIELD, false);
63     }
64     
65     /**
66      * Create a new LuceneSearcher using a specified search index location,
67      * a particular Document field to index, and given read/write status.
68      * @param dir the Lucene Directory indicating the search index to use.
69      * @param field the Lucene Document field that should be indexed.
70      * @param readOnly if this index is read-only or is writable.
71      */

72     public LuceneSearcher(Directory dir, String JavaDoc field, boolean readOnly) {
73         this(dir, new String JavaDoc[]{field}, readOnly);
74     }
75     
76     /**
77      * Create a new LuceneSearcher using a specified search index location,
78      * a particular Document fields to index, and given read/write status.
79      * @param dir the Lucene Directory indicating the search index to use.
80      * @param fields the Lucene Document fields that should be indexed.
81      * @param readOnly if this index is read-only or is writable.
82      */

83     public LuceneSearcher(Directory dir, String JavaDoc[] fields, boolean readOnly) {
84         m_hitCountCache = new HashMap JavaDoc();
85         directory = dir;
86         analyzer = new StandardAnalyzer();
87         this.fields = (String JavaDoc[])fields.clone();
88         try {
89             writer = new IndexWriter(directory, analyzer, !readOnly);
90             writer.close();
91             writer = null;
92         } catch (IOException JavaDoc e1) {
93             e1.printStackTrace();
94         }
95         m_readOnly = readOnly;
96         if ( !readOnly ) {
97             setReadMode(false);
98         } else {
99             m_readMode = false;
100             setReadMode(true);
101         }
102     }
103     
104     // ------------------------------------------------------------------------
105

106     /**
107      * Sets if this LuceneSearcher is in read mode or write mode. In read more
108      * searches can be issued, in write mode new Documents can be indexed.
109      * Read-only LuceneSearcher instances can not be put into write mode.
110      * @param mode true for read mode, false for write mode.
111      * @return true if the mode was successfully set, false otherwise.
112      */

113     public boolean setReadMode(boolean mode) {
114         // return false if this is read-only
115
if ( m_readOnly && mode == false ) return false;
116         // do nothing if already in the mode
117
if ( m_readMode == mode ) return true;
118         // otherwise switch modes
119
if ( !mode ) {
120             // close any open searcher and reader
121
try {
122                 if ( searcher != null ) searcher.close();
123                 if ( reader != null ) reader.close();
124             } catch ( Exception JavaDoc e ) {
125                 e.printStackTrace();
126                 return false;
127             }
128             // open the writer
129
try {
130                 writer = new IndexWriter(directory, analyzer, false);
131             } catch (IOException JavaDoc e1) {
132                 e1.printStackTrace();
133                 return false;
134             }
135         } else {
136             // optimize index and close writer
137
try {
138                 if ( writer != null ) {
139                     writer.optimize();
140                     writer.close();
141                 }
142             } catch (IOException JavaDoc e1) {
143                 e1.printStackTrace();
144                 return false;
145             }
146             // open the reader and searcher
147
try {
148                 reader = IndexReader.open(directory);
149                 searcher = new IndexSearcher(reader);
150             } catch ( Exception JavaDoc e ) {
151                 e.printStackTrace();
152                 return false;
153             }
154         }
155         m_readMode = mode;
156         return true;
157     }
158     
159     /**
160      * Searches the Lucene index using the given query String, returns an object
161      * which provides access to the search results.
162      * @param query the search query
163      * @return the search Hits
164      * @throws ParseException if the query is not parsed successfully
165      * @throws IOException if an input/ouput error occurs
166      * @throws IllegalStateException if the searcher is in write mode
167      */

168     public Hits search(String JavaDoc query) throws ParseException, IOException JavaDoc {
169         if ( m_readMode ) {
170             Query q;
171             if ( fields.length == 1 ) {
172                 q = QueryParser.parse(query, fields[0], analyzer);
173             } else {
174                 q = MultiFieldQueryParser.parse(query, fields, analyzer);
175             }
176             return searcher.search(q);
177         } else {
178             throw new IllegalStateException JavaDoc(
179                     "Searches can only be performed when " +
180                     "the LuceneSearcher is in read mode");
181         }
182     }
183     
184     /**
185      * Return the result count for the given search query. To allow quick
186      * repeated look ups, the hit count is cached (this cache is cleared
187      * whenever a change to the search index occurs).
188      * @param query the search query
189      * @return the number of matches to the query
190      * @throws ParseException if the query is not parsed successfully
191      * @throws IOException if an input/ouput error occurs
192      * @throws IllegalStateException if the searcher is in write mode
193      */

194     public int numHits(String JavaDoc query) throws ParseException, IOException JavaDoc {
195         Integer JavaDoc count;
196         if ( (count=(Integer JavaDoc)m_hitCountCache.get(query)) == null ) {
197             Hits hits = search(query);
198             count = new Integer JavaDoc(hits.length());
199             m_hitCountCache.put(query, count);
200         }
201         return count.intValue();
202     }
203     
204     /**
205      * Add a document to the Lucene search index.
206      * @param d the Document to add
207      * @throws IllegalStateException if the searcher is not in write mode
208      */

209     public void addDocument(Document d) {
210         if ( !m_readMode ) {
211             try {
212                 writer.addDocument(d);
213                 m_hitCountCache.clear();
214             } catch (IOException JavaDoc e) {
215                 e.printStackTrace();
216             }
217         } else {
218             throw new IllegalStateException JavaDoc(
219                     "Documents can not be added to the index unless" +
220                     "the LuceneSearcher is not in read mode");
221         }
222     }
223     
224     /**
225      * Returns the Analyzer used to process text. See Lucene documentation
226      * for more details.
227      * @return returns the analyzer.
228      */

229     public Analyzer getAnalyzer() {
230         return analyzer;
231     }
232     
233     /**
234      * Sets the Analyzer used to process text. See Lucene documentation
235      * for more details.
236      * @param analyzer the analyzer to set
237      */

238     public void setAnalyzer(Analyzer analyzer) {
239         this.analyzer = analyzer;
240     }
241     
242     /**
243      * Returns the indexed Document fields. These fields determine which
244      * fields are indexed as Documents are added and which fields are
245      * queried over when searches are issued.
246      * @return returns the indexed Document fields
247      */

248     public String JavaDoc[] getFields() {
249         return (String JavaDoc[])fields.clone();
250     }
251     
252     /**
253      * Sets the indexed Document fields. These fields determine which
254      * fields are indexed as Documents are added and which fields are
255      * queried over when searches are issued.
256      * param fields the indexed Document fields to use
257      */

258     public void setFields(String JavaDoc[] fields) {
259         this.fields = (String JavaDoc[])fields.clone();
260     }
261     
262     /**
263      * Returns the Lucene IndexReader. See Lucene documentation
264      * for more details.
265      * @return teturns the IndexReader.
266      */

267     public IndexReader getIndexReader() {
268         return reader;
269     }
270     
271     /**
272      * Returns the Lucene IndexSearcher. See Lucene documentation
273      * for more details.
274      * @return returns the IndexSearcher.
275      */

276     public Searcher getIndexSearcher() {
277         return searcher;
278     }
279     
280     /**
281      * Indicates if ths LuceneSearcher is read-only.
282      * @return true if read-only, false if writes are allowed
283      */

284     public boolean isReadOnly() {
285         return m_readOnly;
286     }
287     
288 } // end of class LuceneSearcher
289
Popular Tags