应工作需求,写了个简单lucene索引/检索的实例。就两个main方法,没考虑代码抽象和封装。
lucene包下载: http://labs.mop.com/apache-mirror/lucene/java/3.6.1/ 下载lucene-3.6.1.zip
索引查看工具luke下载 :http://code.google.com/p/luke/downloads/detail?name=lukeall-4.0.0-ALPHA.jar&can=2&q=
第一步、将lucene-core-3.6.1.jar导入工程。
第二步、编写索引的主类:
package com.hkc.action;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateTools;
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.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
public class CreateIndex {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
IndexWriter indexWriter = null;
try {
//索引存放目录
String indexDir = "F:\\LUCENE\\INDEX";
// 创建Directory对象
Directory dir = new SimpleFSDirectory(new File(indexDir));
// 创建IndexWriter对象,第一个参数是Directory,第二个是分词器,第三个表示是否是创建,如果为false为在此基础上面修改,第四表示表示分词的最大值,比如说new
// MaxFieldLength(2),就表示两个字一分,一般用IndexWriter.MaxFieldLength.LIMITED
indexWriter = new IndexWriter(dir, new StandardAnalyzer(
Version.LUCENE_30), true,
IndexWriter.MaxFieldLength.UNLIMITED);
Document doc = new Document();
// 创建Field对象,并放入doc对象中
doc.add(new Field("contents", "hello can i help you",
Field.Store.YES, Field.Index.ANALYZED));
doc.add(new Field("filename", " http://*****/1.html", Field.Store.YES,
Field.Index.NOT_ANALYZED));
doc.add(new Field("indexDate", DateTools.dateToString(new Date(),
DateTools.Resolution.DAY), Field.Store.YES,
Field.Index.NOT_ANALYZED));
// 写入IndexWriter
indexWriter.addDocument(doc);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
indexWriter.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意:在创建Field时,要考虑该字段是否需要索引,是否需要分词。
Field.Index有五个属性,分别是:
Field.Index.ANALYZED:分词索引
Field.Index.NOT_ANALYZED:分词进行索引,如作者名,日期等,Rod Johnson本身为一单词,不再需要分词。
Field.Index.NO:不进行索引,存放不能被搜索的内容如文档的一些附加属性如文档类型, URL等。
Field.Index.NOT_ANALYZED_NO_NORMS:不使用分词索引,不使用存储规则。
Field.Index.ANALYZED_NO_NORMS:使用分词索引,不使用存储规则。
第三步、编写检索类
package com.hkc.action;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
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.SimpleFSDirectory;
import org.apache.lucene.util.Version;
public class Select {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
IndexSearcher indexSearch = null;
try{
//索引存放目录
String indexDir = "F:\\LUCENE\\INDEX";
Directory dir = new SimpleFSDirectory(new File(indexDir));
//创建 IndexSearcher对象
indexSearch = new IndexSearcher(dir);
//创建QueryParser对象,第一个参数表示Lucene的版本,第二个表示搜索Field的字段,第三个表示搜索使用分词器
QueryParser queryParser = new QueryParser(Version.LUCENE_30,
"contents", new StandardAnalyzer(Version.LUCENE_30));
//生成Query对象
Query query = queryParser.parse("hello"); //查询hello这个词
//搜索结果 TopDocs里面有scoreDocs[]数组,里面保存着索引值
TopDocs hits = indexSearch.search(query, 10);
//hits.totalHits表示一共搜到多少个
System.out.println("找到了"+hits.totalHits+"个");
//循环hits.scoreDocs数据,并使用indexSearch.doc方法把Document还原,再拿出对应的字段的值
for (int i = 0; i < hits.scoreDocs.length; i++) {
ScoreDoc sdoc = hits.scoreDocs[i];
Document doc = indexSearch.doc(sdoc.doc);
System.out.println(doc.get("filename"));
System.out.println(doc.get("contents"));
}
indexSearch.close();
}catch(Exception e){
e.printStackTrace();
}finally{
try {
indexSearch.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
由于lucene自带标准分词器不支持中文分词, 下篇将对引入其他分词器来解决该问题