Lucene 기본 응용 사례

다음 두 코드 세그먼트는 각각 lucene 색인을 만들고 lucene을 통해 검색하는 방법을 보여 줍니다.
1. 지정한 데이터 테이블의 인덱스 만들기
indexDirPath는 색인 파일의 저장 경로입니다.clearDir는 색인을 만들 때마다 폴더를 비울 지 여부를 가리킨다.batch Indexing Dao는 데이터를 추출하기 위한 DAO 인터페이스로 공공 List get Batch Records(String tableName, int begin Index, int count)가 있습니다.방법은 차례로 나누어 표에서 데이터를 추출하는 데 쓰인다.일반적으로 이 인터페이스는 특정 Dao에 의해 구현됩니다.tableName, 인덱스가 필요한 데이터 테이블에 사용합니다.사실 이 매개 변수는 나타나지 말아야 한다. 그것은 특정한 DAO에 의해 봉인되어야 한다.이것은 프로그램 중의 특수한 원인 때문이다.indexDocWrapper는 spirngjdbc의rowmapper와 매우 재미있는 인터페이스입니다. DAO가 되돌아오는 실체 대상을 감싸거나 루틴의 Document 대상으로 어울리기 때문입니다.
/**
	 * Creates index. This is generic method for creating index.
	 *
	 * @param <T> the object type which will be indexed.
	 * @param indexFileDir the index file's directory.
	 * @param clearDir whether clear the direcory first when creating index.
	 * @param batchIndexingDao the batch indexing dao, it's used to load objects from database when indexing.
	 * @param tableName the table name. there are many topic and reply daily tables.
	 * @param indexDocWrapper the wrapper to wrap an object into document.
	 */
	public <T> void createIndex(String indexDirPath, boolean clearDir, BatchIndexingDao batchIndexingDao ,String tableName , IndexDocWrapper<T> indexDocWrapper){	
		IndexWriter writer = null;
		try {
			File indexFileDir = new File(indexDirPath);
			if(indexFileDir.exists()&&clearDir==true){
				FileUtils.cleanDirectory(indexFileDir);
				logger.info("The specified direcory:" + indexDirPath +" has cleared.");
			}
			writer = new IndexWriter(FSDirectory.open(indexFileDir), new IKAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
			writer.setRAMBufferSizeMB(Constants.INDEX_WRITER_RAM_BUFFER);
			int recordIndex = 0;
			List<T> objects = null;
			do {
				try {
					objects = batchIndexingDao.getBatchRecords(tableName, recordIndex, Constants.BATCH_INDEX_SIZE);
				} catch (BadSqlGrammarException e) {
					logger.error(tableName+" does not exist!");
					continue;
				}
				if (objects != null && !objects.isEmpty()) {
					for (T object : objects) {
						writer.addDocument(indexDocWrapper.createDoc(object));
					}
					logger.info(recordIndex + objects.size() + " records has added!");
					recordIndex += Constants.BATCH_INDEX_SIZE;
				}
			} while (objects != null && !objects.isEmpty());
			logger.info("Starts to optimize...");
			writer.optimize();
			logger.info("Optimize finished.");
		} catch (CorruptIndexException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} finally {
			if(writer!=null){
				try {
					writer.close();
					logger.info("Topic indexing work finished.");
				} catch (CorruptIndexException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

2. 주어진 키워드에 따라 적중한 대상을 검색한다
indexDirPath는 색인 파일의 저장 경로입니다.field 는 검색되는 Lucene Document 의 field 입니다.expression은 lucene 표현식입니다.indexObjectWrapper와 indexDocWrapper는 대응합니다. 루틴의 Document를 추출하여 대상에 봉인한 소포기입니다.beginIndex와count는 검색 결과가 많을 때 페이지를 나누는 데 사용됩니다.
/**
	 * Search. This is generic method for searching with paging.
	 *
	 * @param <T>  the searching target object type.
	 * @param indexFileDir the index file dir
	 * @param field the document field for searching.
	 * @param expression the expression
	 * @param indexObjectWrapper the index object wrapper
	 * @param beginIndex the begin index
	 * @param count the count
	 * @return the list
	 */
	public <T> List<T> search(String indexFileDir, String field,  String expression, IndexObjectWrapper<T> indexObjectWrapper, int beginIndex, int count){
		IndexSearcher indexSearcher = null;
		try {
			logger.info("Starts to search...");
			if(expression==null||"".equals(expression.trim())){
				throw new NullPointerException("The lucene expression is null or empty!");
			}
			indexSearcher = new IndexSearcher(FSDirectory.open(new File(indexFileDir)));
			Query query = new QueryParser(Version.LUCENE_CURRENT, field, new IKAnalyzer()).parse(expression);
			TopDocs topDocs = indexSearcher.search(query, Integer.MAX_VALUE);
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			logger.info("Total Hits: "+topDocs.totalHits);
			List<T> objects = new ArrayList<T>();
			int endIndex = beginIndex+count;
			for (int i = beginIndex; i < endIndex; i++) {
				Document targetDoc = indexSearcher.doc(scoreDocs[i].doc);
				objects.add(indexObjectWrapper.createObject(targetDoc));
			}
			return objects;
		}  catch (Exception e) {
			logger.info(e.getMessage());
			e.printStackTrace();
			return null;
		} finally {
			if(indexSearcher!=null){
				try {
					indexSearcher.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

좋은 웹페이지 즐겨찾기