lucene的jar包:lucene-core-3.6.2.jar
使用的中文分词:IKAnalyzer3.2.8.jar
/**
* 2013.06.06
* lucene学习,创建索引,搜索
* @author 赵洪志
*/
package com.zhao.lucene.indexes;
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;
public class CreateIndex {
/**
* @param args
* @throws IOException
* @throws LockObtainFailedException
* @throws CorruptIndexException
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
String fieldName = "content";
String content = "我的一个lucene创建index的测试案例,我将用它来测试搜索";
// 实例化IK分析器boolean isMaxWordLength默认最细粒度切分算法,为true时,分词器进行最大词长切分,貌似2012版本使用智能分词
Analyzer analyzer = new IKAnalyzer();
Directory directory = null;
IndexWriter writer = null;
IndexSearcher searcher = null;
try {
// 把索引创建在内存里
directory = new RAMDirectory();
// 实例化IndexWriter
writer = new IndexWriter(directory, analyzer,
IndexWriter.MaxFieldLength.UNLIMITED);
// 创建Document,相当于SQL中的一条记录
Document doc = new Document();
// 添加域值,相当于SQL中列的值
doc.add(new Field(fieldName, content, Field.Store.YES,
Field.Index.ANALYZED));
writer.addDocument(doc);
writer.close();
System.out.println("索引创建成功!");
// 开始搜索
searcher = new IndexSearcher(directory);
// 在搜索中使用IKSimilarity相似度评估器
searcher.setSimilarity(new IKSimilarity());
// 搜索关键词
String keyword = "测试搜索";
// 使用IK的QueryParser
Query query = IKQueryParser.parse(fieldName, keyword);
// 返回符合条件的记录
TopDocs docs = searcher.search(query, 1);
System.out.println("查询语句为:" + query.toString());
System.out.println("查询结果为:" + docs.totalHits);
ScoreDoc[] sd = docs.scoreDocs;
for (int i = 0; i < sd.length; i++) {
Document document = searcher.doc(sd[i].doc);
System.out.println(document);
}
} catch (Exception ex) {
} finally {
if (searcher != null) {
try {
searcher.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
if (directory != null) {
try {
directory.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
}
创建索引时参数的一些描述
*域索引
*Field.Index.NO使对应的域值不被索引
*Field.Index.ANALYZED使用分析器将域值分解成独立的单元词汇,每个单元词汇都能被搜索,适用普通文本,正文、标题、摘要等。
*Field.Index.ANALYZED_NO_NORMS功能同上,但不记录NORMS信息,NORMS保存了索引中的boost信息,
*Field.Index.NOT_ANALYZED对域值进行索引,但不使用分析器拆分,适用精确搜索,如人名、日期、电话号码
*Field.Index.NOT_ANALYZED_NO_NORMS同上,但不记录NORMS信息,在搜索时消耗内存较少。
*域存储
*Field.Store.YES指定存储域值,原始字符串被保存在索引中,可以恢复,主要用来保存URL、标题、数据库主键。
*Field.Store.NO指定不存储域值,通常跟Field.Index.ANALYZED一起用来索引大文本,如web正文
注意:
只有分析器产生的词汇单元才能被搜索到,例外情况是索引对应的域时使用Field.Index.NOT_ANALYZED, Field.Index.NOT_ANALYZED_NO_NORMS选项,该情况下整个域值作为一个语汇单元,可以被搜索到。