背景:下阶段工作需要实现全文检索功能,查阅信息决定以lucene实现
使用版本:lucene-4.2.1
下载地址:http://mirrors.cnnic.cn/apache/lucene/java/4.2.1/
API地址:http://lucene.apache.org/core/4_2_1/index.html
网上搜索找到以下学习地址:http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/
http://www.liutime.com/java_circlescontentinfo/id=706
http://xuehanxin.iteye.com/blog/1850829
基本知识摘录:
Lucene 五个基础的类 Document, Field, IndexWriter, Analyzer, Directory 用途:
Document
Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。
Field
Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。
Analyzer
在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。
IndexWriter
IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。
Directory
这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。
具体实现代码:
jar包:
lucene-core-4.2.1.jar
lucene-queryparser-4.2.1.jar
lucene-analyzers-common-4.2.1.jar
待检索文件:
存放:D:\testlucene\docs
代码:
public class LuceneIndex {
//该函数用于创建索引。可以将其写成一个单独的类。
public void createIndex() throws IOException{
//数据存放文件夹
File f_doc=new File("D:\\testlucene\\docs");
//索引存放文件夹
File f_idx=new File("D:\\testlucene\\index");
//directory参数,用于传入IndexWriter
Directory directory=FSDirectory.open(f_idx);
//conf参数,用于传入IndexWriter.
IndexWriterConfig conf=new IndexWriterConfig(Version.LUCENE_42,new StandardAnalyzer(Version.LUCENE_42));
IndexWriter writer=new IndexWriter(directory,conf);
//对数据文件夹下面的所有文件建立索引;
File[] textFiles =f_doc.listFiles();
for(int i=0;i<textFiles.length;i++){
if(textFiles[i].isFile()){
Document document=new Document();//注意,这个Document必须在循环中创建
System.out.println( " File"+ textFiles[i].getCanonicalPath() +"正在被索引 . " );
FileInputStream temp=new FileInputStream (textFiles[i]);
//获取文件内容
int len=temp.available();
byte[] buffer=new byte[len];
temp.read(buffer);
temp.close();
String content = new String(buffer, "GBK"); //测试发现需要转换编码
// String content=new String(buffer);
// System.out.println("content = "+ content);//测试文件内容
//加入Field
document.add(new Field("path", textFiles[i].getPath(), TextField.TYPE_STORED));
document.add(new Field("body", content, TextField.TYPE_STORED));
writer.addDocument(document);
writer.commit();//必须先提交,不然的会报错!
}
}
System.out.println("索引的数目:"+writer.numDocs());
writer.close();
}
//查询函数
public void TestQuery(String querystring) throws IOException,ParseException{
//创建一个IndexSearcher
File f=new File("D:\\testlucene\\index");
Directory directory =FSDirectory.open(f);
IndexReader ireader=DirectoryReader.open(directory);
IndexSearcher searcher=new IndexSearcher(ireader);//这个和以前的版本有所变化。
//查询词解析
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_42);
QueryParser parser=new QueryParser(Version.LUCENE_42,"body",analyzer);
Query query=parser.parse(querystring);
//以前的Hits已经不再使用。直接使用TopDocs即可。
Filter filter = null;
TopDocs topDocs = searcher.search(query, filter, 10);//最后一个参数,限制查询结果的条目。
System.out.println("总共有【" + topDocs.totalHits + "】条匹配结果");
//显示结果
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
//文档内部编
int index = scoreDoc.doc;
//根据编号取出相应的文档
Document doc =searcher.doc(index);
System.out.println("------------"+index+1+"----------------");
System.out.println("path = " + doc.get("path"));
System.out.println("content = " + doc.get("body"));
}
ireader.close();
}
//主函数
public static void main(String[] args) throws IOException, ParseException{
LuceneIndex ix=new LuceneIndex();
//检索词
String querystring="内容";
ix.createIndex();//该句用于创建索引,第一次运行时将"//"去掉,以后就加上注释,不然索引会重复创建。
System.out.println("您的检索词为:【"+querystring+"】");
ix.TestQuery(querystring);
System.out.println("检索结束 ----");
}
}
存在问题:
1、英文单词检索不出来
2、多目录检索未实现
待学习多目录: