lucene教程
luence是一个非常好的检索工具,,使用简单,几行代码就能搞定。
Lucene的架构设计及介绍
这个架构分为两部分,一是建立索引,从数据源建立相应的索引机制,二是索引查询,输入关键词,根据索引,查找并且返回结果。
1.lucene包
org.apache.Lucene.search/ | 搜索入口 |
org.apache.Lucene.index/ | 索引入口 |
org.apache.Lucene.analysis/ | 语言分析器 |
org.apache.Lucene.queryParser/ | 查询分析器 |
org.apache.Lucene.document/ | 存储结构 |
org.apache.Lucene.store/ | 底层IO/存储结构 |
org.apache.Lucene.util/ | 一些公用的数据结构 |
2.索引过程的核心类
·IndexWriter
·Directory
·Analyzer
·Document
·Field
①IndexWriter
索引过程的核心组件。这个类负责创建新索引或者打开已有索引,以及向索引中添加、删除或更新被索引文档的信息。可以把IndexWriter看作这样一个对象:它为你提供针对索引文件的写入操作,但不能用于读取或搜索索引。IndexWriter需要开辟一定空间来存储索引,该功能可以由Directory完成。
②Directory
该类描述了Lucene索引的存放位置。它是一个抽象类,它的子类负责具体指定索引的存储路径。用FSDirectory.open方法来获取真实文件在文件系统的存储路径,然后将它们一次传递给IndexWriter类构造方法。IndexWriter不能直接索引文本,这需要先由Analyzer将文本分割成独立的单词才行。
③Analyzer
文本文件在被索引之前,需要经过Analyzer(分析器)处理。Analyzer是由IndexWriter的构造方法来指定的,它负责从被索引文本文件中提取语汇单元,并提出剩下的无用信息。如果被索引内容不是纯文本文件,那就需要先将其转换为文本文档。对于要将Lucene集成到应用程序的开发人员来说,选择什么样Analyzer是程序设计中非常关键的一步。分析器的分析对象为文档,该文档包含一些分离的能被索引的域。
④Document
Document对象代表一些域(Field)的集合。文档的域代表文档或者文档相关的一些元数据。元数据(如作者、标题、主题和修改日期等)都作为文档的不同域单独存储并被索引。Document对象的结构比较简单,为一个包含多个Filed对象容器;Field是指包含能被索引的文本内容的类。
⑤Field
索引中的每个文档都包含一个或多个不同命名的域,这些域包含在Field类中。每个域都有一个域名和对应的域值,以及一组选项来精确控制Lucene索引操作各个域值。
3.搜索过程中的核心类
IndexSearcher
·Term
·Query
·TermQuery
·TopDocs
①IndexSearcher
该类用于搜索由IndexWriter类创建的索引,它是连接索引的中心环节。可以将IndexSearcher类看作是一个以只读方式打开索引的类。它需要利用Directory实例来掌控前期创建的索引,然后才能提供大量的搜索方法。
②Term
Term对象是搜索功能的基本单元。Term对象包含一对字符串元素:域名和单词(或域名文本值)。
③Query
包含了一些非常有用的方法,TermQuery是它的一个子类。
④TermQuery
该类提供最基本的查询,用来匹配指定域中包含特定项的文档。
⑤TopDocs
该类是一个简单的指针容器,指针一般指向前N个排名的搜索结果,搜索结果即匹配查询条件的文档。
建立索引
首先 我在桌面建立数据源
其次 我把索引目录放在 C:\Users\Administrator\Desktop\xxxx上
加入maven包
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>4.0.0</version>
</dependency>
完整的代码实现
Directory directory = FSDirectory.open(new File("C:\\Users\\Administrator\\Desktop\\xxxx"));
File sourceDirectory = new File("C:\\Users\\Administrator\\Desktop\\yyyy");
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);
IndexWriter iwriter = new IndexWriter(directory, config);
for (int i = 0; i < sourceDirectory.listFiles().length; i++) {
Document doc = new Document();
File fi = sourceDirectory.listFiles()[i];
//基于Reader实现
Reader txtReader = new FileReader(sourceDirectory.listFiles()[i]);
doc.add(new TextField("content1", txtReader));
BufferedReader reader = new BufferedReader(new FileReader(fi));
String temp = null;
StringBuffer sb = new StringBuffer();
while ((temp = reader.readLine()) != null) {
sb.append(temp);
}
reader.close();
String context = sb.toString();
System.out.print(context);
doc.add(new TextField("content2", context, Store.YES));
doc.add(new TextField("path", fi.getAbsolutePath(), Store.YES));
iwriter.addDocument(doc);
}
iwriter.close();
查询
Directory directory = FSDirectory.open( new File("C:\\Users\\Administrator\\Desktop\\xxxx"));
String text = "hello";
DirectoryReader ireader = DirectoryReader.open(directory);
IndexSearcher isearcher = new IndexSearcher(ireader);
Term term = new Term("content2", text.toLowerCase());
TermQuery termQuery = new TermQuery(term);
QueryScorer scorer = new QueryScorer(termQuery);
SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter("<B>","</B>");//设定高亮显示的格式<B>keyword</B>,此为默认的格式
Highlighter highlighter = new Highlighter(simpleHtmlFormatter,scorer);
highlighter.setTextFragmenter(new SimpleFragmenter(20));//设置每次返回的字符数
ScoreDoc[] hits = isearcher.search(termQuery,10000).scoreDocs;
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
for (int i = 0; i < hits.length; i++) {
Document hitDoc = isearcher.doc(hits[i].doc);
System.out.print(hitDoc.get("content1")+"\n");
System.out.print(hitDoc.get("content2")+"\n");
System.out.print(hitDoc.get("path")+"\n");
String str = highlighter.getBestFragment(analyzer, "content2", hitDoc.get("content2")) ;
System.out.println(str);
}
ireader.close();
directory.close();
运行结果
C:\Users\Administrator\Desktop\yyyy\bb.txt
<B>Hello</B> world��Do say
C:\Users\Administrator\Desktop\yyyy\cc.txt
<B>Hello</B> world��Do say
C:\Users\Administrator\Desktop\yyyy\aa.txt
<B>Hello</B> world��Do say
参考文档
http://lucene.apache.org/core/4_0_0/core/overview-summary.html