Java tutorial
/******************************************************************************* * Copyright (c) 2008 Jeong Ju Ho. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Jeong Ju Ho - initial API and implementation ******************************************************************************/ package org.jhlabs.scany.engine.search; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.store.Directory; import org.jhlabs.scany.engine.entity.Record; import org.jhlabs.scany.engine.entity.RecordList; import org.jhlabs.scany.engine.entity.Relation; import org.jhlabs.scany.engine.index.RecordKeyException; import org.jhlabs.scany.engine.search.extract.PagingRecordExtractor; import org.jhlabs.scany.engine.search.extract.RandomRecordExtractor; import org.jhlabs.scany.engine.search.extract.RecordExtractor; import org.jhlabs.scany.engine.search.extract.SequentialRecordExtractor; import org.jhlabs.scany.engine.search.paging.IterablePaging; import org.jhlabs.scany.engine.search.query.LuceneQueryBuilder; import org.jhlabs.scany.engine.search.query.QueryBuilderException; /** * . * * + ? * ? ? ? ? . * * + ? * ? ? ? , * ? ?? ? ? ? . * * + ? * ? ? ? ? . * ? ??? . * ()? ? ?? ?? ?? ? ?? ? ?? . * ? ? ? ??? ? ?? ? ? ? . * * <p>Created: 2007. 01. 19 1:29:18</p> * * @author Gulendol * */ public class LuceneSearcher extends SearchModel implements AnySearcher { /** * ?? * @param relation * @throws ScanySearchException */ public LuceneSearcher(Relation relation) throws AnySearcherException { super(relation); } /** * ?? ? ? . * ? ? 1 ? . * @param queryText * @return * @throws AnySearcherException */ public RecordList search(String queryText) throws AnySearcherException { return search(queryText, 1); } /** * ?? ? ? . * ? . * @param queryText * @return * @throws AnySearcherException */ public RecordList search(int pageNo) throws AnySearcherException { return search(null, pageNo); } /** * ?? ? ? . * ?? , ? ? null? . * Record[0]? . * ? () ?? null? , * , ? ?? ?. * @param queryText ? ? * @param pageNo ? * @return hitsPerPage ?? Record . * @throws AnySearcherException */ public RecordList search(String queryText, int page) throws AnySearcherException { if (page <= 0) return null; try { setQueryText(queryText); setPage(page); RecordExtractor recordExtractor = new PagingRecordExtractor((SearchModel) this); search((SearchModel) this, recordExtractor); return recordExtractor.getRecordList(); } catch (Exception e) { throw new AnySearcherException("Search failed.", e); } } /** * ? ? . * ? . * ? . * @return hitsPerPage ? * @throws AnySearcherException */ public RecordList random() throws AnySearcherException { return random(null); } /** * ? ? . * ? ? . * ? . * ? () ?? null? , * , ? ?? ?. * @param queryText ? * @return hitsPerPage ? * @throws AnySearcherException */ public RecordList random(String queryText) throws AnySearcherException { try { setQueryText(queryText); RecordExtractor recordExtractor = new RandomRecordExtractor((SearchModel) this); search((SearchModel) this, recordExtractor); return recordExtractor.getRecordList(); } catch (Exception e) { throw new AnySearcherException("Random search failed.", e); } } /** * (Record) ?? ? ? ? ? ? ? . * ()? ? ? ?? ??? ? ? . * ? () ?? null? , * , ? ?? ?. * @param start ? * @param maxRecords * @param reverse * @return * @throws AnySearcherException */ public RecordList seek(int start, int maxRecords, boolean reverse) throws AnySearcherException { if (start < 0) return null; try { setPage(1); setStartRecord(start); setHitsPerPage(maxRecords); setReverse(reverse); RecordExtractor recordExtractor = new SequentialRecordExtractor((SearchModel) this); search((SearchModel) this, recordExtractor); return recordExtractor.getRecordList(); } catch (Exception e) { throw new AnySearcherException("Sequential search failed.", e); } } public Iterator<Record> interator(int numHitsToCollect) throws AnySearcherException { return interator(null, numHitsToCollect); } public Iterator<Record> interator(String queryText, int numHitsToCollect) throws AnySearcherException { try { setQueryText(queryText); Analyzer analyzer; if (getRelation().getPerFieldAnalyzer() != null) analyzer = getRelation().getPerFieldAnalyzer(); else analyzer = getRelation().getAnalyzer(); LuceneQueryBuilder queryBuilder = new LuceneQueryBuilder(); queryBuilder.addQuery(getFilterAttributeList()); queryBuilder.addQuery(getParsedQueryText(), getQueryAttributeList(), analyzer); Query query = queryBuilder.build(); IterablePaging iter = new IterablePaging((SearchModel) this, query, numHitsToCollect); iter.skipTo(getStartRecord()); iter.gather(getHitsPerPage()); return iter.iterator(); } catch (Exception e) { throw new AnySearcherException("search failed.", e); } } public static RecordList search(SearchModel searchModel, RecordExtractor recordExtractor) throws QueryBuilderException, RecordKeyException, IOException, ParseException { IndexSearcher indexSearcher = null; try { Directory directory = searchModel.getRelation().openDirectory(); indexSearcher = new IndexSearcher(directory); Analyzer analyzer; if (searchModel.getRelation().getPerFieldAnalyzer() != null) analyzer = searchModel.getRelation().getPerFieldAnalyzer(); else analyzer = searchModel.getRelation().getAnalyzer(); LuceneQueryBuilder queryBuilder = new LuceneQueryBuilder(); queryBuilder.addQuery(searchModel.getFilterAttributeList()); queryBuilder.addQuery(searchModel.getParsedQueryText(), searchModel.getQueryAttributeList(), analyzer); Query query = queryBuilder.build(); query = indexSearcher.rewrite(query); List<SortAttribute> sortAttributeList = searchModel.getSortAttributeList(); Sort sort = null; if (sortAttributeList != null && sortAttributeList.size() > 0) sort = SearchModelUtils.makeSort(searchModel.getSortAttributeList()); ScoreDoc[] docs = null; if (sort == null) { TopDocs topDocs = indexSearcher.search(query, searchModel.getHitsPerPage()); docs = topDocs.scoreDocs; searchModel.setTotalRecords(topDocs.totalHits); } else { TopFieldDocs topFieldDocs = indexSearcher.search(query, searchModel.getHitsPerPage(), sort); docs = topFieldDocs.scoreDocs; searchModel.setTotalRecords(topFieldDocs.totalHits); } recordExtractor.extract(indexSearcher.getIndexReader(), docs); return recordExtractor.getRecordList(); } finally { try { if (indexSearcher != null) indexSearcher.close(); } catch (Exception e2) { e2.printStackTrace(); } } } }