背景:下阶段工作需要实现全文检索功能,查阅信息决定以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、多目录检索未实现
待学习多目录: