Lucene基本应用示例
Lucene基本应用示例
猪刚烈 发表于3年前
Lucene基本应用示例
  • 发表于 3年前
  • 阅读 8
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

以下两段代码分别展示如何创建lucene索引和通过lucene进行检索:

1.为指定的数据表创建索引

indexDirPath是索引文件的存放路径。clearDir是指明是否在每次建立索引时清空文件夹。batchIndexingDao是专来提取数据的DAO接口,它有一个public <T> List<T> getBatchRecords(String tableName, int beginIndex, int count);方法用来分批次的从表中提取数据。此接口一般由某具体Dao实现。tableName,用于需要做索引的数据表。其实这个参数是不应该出现的,它应该由某个具体的DAO封装起来了。这里是由于程序中的特殊原因。indexDocWrapper是很有意思的一个接口,它很像spirngjdbc的rowmapper,由于把DAO返回的实体对象包裹或者说适配成lucene的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是对应的,当是把lucene的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();
				}
			}
		}
	}


共有 人打赏支持
粉丝 22
博文 708
码字总数 110
作品 1
×
猪刚烈
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: