一:环境:eclipse+lucene-core-3.5.0.jar+lucene-analyzers-3.5.0.jar
二:主要类介绍
1、创建索引主要类
为了对文档进行索引,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,它表示一个存储在内存当中的索引的位置。熟悉了建立索引所需要的这些类后,我们就开始对某个目录下面的文本文件建立索引了,清单 1 给出了对某个目录下的文本文件建立索引的源代码。
2、搜索主要类:
利用 Lucene 进行搜索就像建立索引一样也是非常方便的。在上面一部分中,我们已经为一个目录下的文本文档建立好了索引,现在我们就要在这个索引上进行搜索以找到包含某个关键词或短语的文档。Lucene 提供了几个基础的类来完成这个过程,它们分别是呢 IndexSearcher, Term, Query, TermQuery, Hits. 下面我们分别介绍这几个类的功能。
Query
这是一个抽象类,他有多个实现,比如 TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成 Lucene 能够识别的 Query。
Term
Term 是搜索的基本单位,一个 Term 对象有两个 String 类型的域组成。生成一个 Term 对象可以有如下一条语句来完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一个参数代表了要在文档的哪一个 Field 上进行查找,第二个参数代表了要查询的关键词。
TermQuery
TermQuery 是抽象类 Query 的一个子类,它同时也是 Lucene 支持的最为基本的一个查询类。生成一个 TermQuery 对象由如下语句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的构造函数只接受一个参数,那就是一个 Term 对象。
IndexSearcher
IndexSearcher 是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个 IndexSearcher 的实例在一个索引上进行操作。
Hits
Hits 是用来保存搜索的结果的。
介绍完这些搜索所必须的类之后,我们就开始在之前所建立的索引上进行搜索了,清单 2 给出了完成搜索功能所需要的代码。
三:工程结构
四:创建索引代码及搜素代码HelloLucene类如下:
package org.itat.test; import java.io.File; import java.io.FileReader; import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryParser.ParseException; 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.FSDirectory; import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.Version; /** * Lucene demo 创建索引及搜索 * @author Administrator * */ public class HelloLucene { /** * 建立索引 */ public void index(){ IndexWriter writer=null; try { // 1、创建Directory; 创建索引库 //Directory directory=new RAMDirectory(); // 创建在内存中 Directory directory=FSDirectory.open(new File("D:/lucene/index01")); //创建在硬盘中 // 2、创建IndexWriter 写索引 ; StandardAnalyzer 分词器 IndexWriterConfig iwc=new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)); writer=new IndexWriter(directory,iwc); // 3、创建Document 对象 Document doc=null; // 4、为Document添加field File f=new File("D:/lucene/example"); // 遍历文档中的文件 for (File file : f.listFiles()) { doc=new Document(); // 获得文件内容; new FileReader(file):读取一个文件 doc.add(new Field("content", new FileReader(file))); /* Field.Store.YES 是否把文件全名存在硬盘中 ; Field.Index.NOT_ANALYZED) 是否进行分词 * 获得文件名 (对于文件名没必要进行分词,它本身就是一个完整的词) */ doc.add(new Field("filename", file.getName(),Field.Store.YES,Field.Index.NOT_ANALYZED)); //获得文件路径 doc.add(new Field("path", file.getAbsolutePath(),Field.Store.YES,Field.Index.NOT_ANALYZED)); // 5、通过IndexWriter添加文档到索引 writer.addDocument(doc); } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (LockObtainFailedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if (writer !=null) try { // 关闭IndexWriter writer.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 搜索 */ public void sercher(){ try { //1、创建 Directory Directory directory = FSDirectory.open(new File("D:/lucene/index01")); //创建在硬盘中 //2、创建 IndexReader 读取所有索引 IndexReader reader=IndexReader.open(directory); //3、根据IndexReader 创建IndexSearcher IndexSearcher searcher=new IndexSearcher(reader); //4、创建parser来确定 搜索文件的内容 第二个 参数表示要搜索的域 QueryParser parser=new QueryParser(Version.LUCENE_35, "content", new StandardAnalyzer(Version.LUCENE_35)); Query query=parser.parse("java"); // 查询content中包含java的文档 //5、根据 searcher搜索并返回TopDocs TopDocs tds=searcher.search(query, 5); // 取多少条数据 //6、根据TopDocs获取ScoreDoc对象 ScoreDoc[] sds=tds.scoreDocs; //所有文档所存的id号 for (ScoreDoc sd : sds) { //7、根据searcher和 ScoreDoc获取具体的Document对象 Document d=searcher.doc(sd.doc); //8、根据Document 对象 获取需要的值 System.out.println(d.get("filename")+"["+d.get("path")+"]"); } //9、关闭reader reader.close(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
五:测试类TestLucene如下:
package org.itat.test; public class TestLucene { /** * 测试创建索引 */ public static void testIndex(){ HelloLucene hl=new HelloLucene(); hl.index(); } /** * 测试搜索 */ public static void testSearcher(){ HelloLucene hl=new HelloLucene(); hl.sercher(); } public static void main(String[] args) { //TestLucene.testIndex(); TestLucene.testSearcher(); } }
七:索引所在目录
八:结果