• 欢迎访问web前端中文站,JavaScript,CSS3,HTML5,web前端demo
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏web前端中文站吧

Lucene 安装和应用实战

JAVA web前端中文站 2年前 (2017-10-07) 877次浏览 已收录 0个评论

这篇文章我们将进入 Lucene 的实战阶段,我们将通过 Lucene 的一个简单入门程序,来实现它对全文检索,高效的搜索应用。

更多精彩内容请看 web 前端中文站
http://www.lisa33xiaoq.net 可按 Ctrl + D 进行收藏

Lucene 安装和应用实战

Lucene框架图

下载

http://jakarta.apache.org/lucene/

Lucene中的一些比较复杂的词法分析是用 JavaCC 生成的(JavaCC:JavaCompilerCompiler,纯 Java 的词法分析生成器),所以如果从源代码编译或需要修改其中的 QueryParser、定制自己的词法分析器,还需要从 https://javacc.dev.java.net/下载 javacc。

lucene 的组成结构

对于外部应用来说索引模块(index)和检索模块(search)是主要的外部应用入口。

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/ 一些公用的数据结构

索引过程

从命令行读取文件名(多个),将文件分路径(path 字段)和内容(body 字段)2 个字段进行存储,并对内容进行全文索引。索引的单位是 Document 对象,每个 Document 对象包含多个字段 Field 对象,针对不同的字段属性和数据输出的需求,对字段还可以选择不同的索引/存储字段规则,列表如下:

方法 切词 索引 存储 用途
Field.Text(String name, String value) Yes Yes Yes 切分词索引并存储,比如:标题,内容字段
Field.Text(String name, Reader value) Yes Yes No 切分词索引不存储,比如:META 信息,
不用于返回显示,但需要进行检索内容
Field.Keyword(String name, String value) No Yes Yes 不切分索引并存储,比如:日期字段
Field.UnIndexed(String name, String value) No No Yes 不索引,只存储,比如:文件路径
Field.UnStored(String name, String value) Yes Yes No 只全文索引,不存储

看下面的一个简单的 Lucene 搜索程序:

 public class IndexFiles {    
 //使用方法:: IndexFiles [索引输出目录] [索引的文件列表] ...  
  public static void main(String[] args) throws Exception {   
 String indexPath = args[0];   
 IndexWriter writer;   
 //用指定的语言分析器构造一个新的写索引器(第 3 个参数表示是否为追加索引)
 /*更多前端文章,见 www.lisa33xiaoq.net*/    
 writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false);   
 for (int i=1; i<args.length; i++) {    
 System.out.println("Indexing file " + args[i]);    
 InputStream is = new FileInputStream(args[i]);    
 //构造包含 2 个字段 Field 的 Document 对象    
 //一个是路径 path 字段,不索引,只存储    
 //一个是内容 body 字段,进行全文索引,并存储    
 Document doc = new Document();    
 doc.add(Field.UnIndexed("path", args[i]));    
 doc.add(Field.Text("body", (Reader) new InputStreamReader(is)));    
 //将文档写入索引    
 writer.addDocument(doc);    
 is.close();   };   
 //关闭写索引器  
 writer.close();  } }

上面是一个创建索引的过程,索引过程中可以看到:

  • 语言分析器提供了抽象的接口,因此语言分析(Analyser)是可以定制的,虽然 lucene 缺省提供了 2 个比较通用的分析器 SimpleAnalyser 和 StandardAnalyser,这 2 个分析器缺省都不支持中文,所以要加入对中文语言的切分规则,需要修改这 2 个分析器。
  • Lucene 并没有规定数据源的格式,而只提供了一个通用的结构(Document 对象)来接受索引的输入,因此输入的数据源可以是:数据库,WORD 文档,PDF 文档,HTML 文档……只要能够设计相应的解析转换器将数据源构造成成 Docuement 对象即可进行索引。
  • 对于大批量的数据索引,还可以通过调整 IndexerWrite 的文件合并频率属性(mergeFactor)来提高批量索引的效率。

检索过程

搜索结果返回的是 Hits 对象,可以通过它再访问 Document==>Field 中的内容。

假设根据 body 字段进行全文检索,可以将查询结果的 path 字段和相应查询的匹配度(score)打印出来。看下面的一个搜索案例:

 public class Search {   
 public static void main(String[] args) throws Exception {   
 String indexPath = args[0], queryString = args[1];   
 //指向索引目录的搜索器   
 Searcher searcher = new IndexSearcher(indexPath);   
 //查询解析器:使用和索引同样的语言分析器   
 Query query = QueryParser.parse(queryString, "body",            
 new SimpleAnalyzer());   
 //搜索结果使用 Hits 存储   
 Hits hits = searcher.search(query);   
 //通过 hits 可以访问到相应字段的数据和查询的匹配度   
 for (int i=0; i<hits.length(); i++) {     
 System.out.println(hits.doc(i).get("path") + "; Score: " + hits.score(i)); };  } }

在整个检索过程中,语言分析器,查询分析器,甚至搜索器(Searcher)都是提供了抽象的接口,可以根据需要进行定制。

上面简单的百把行代码,就实现了一个 Lucene 检索应用。但是实际使用过程中,还有很多的需求和功能,例如:对内容修改了呢?还有对搜索结果的排序,人工排序,权重干扰,索引优化,分布式等。后面我们继续深入学习!

相关文章推荐:

1、LUCENE 如何对索引进行搜索?

2、详解 LUCENE 对 TERM 的权重(TERM WEIGHT) 计算

3、LUCENE 全文检索不等于 LIKE “%KEYWORD%”

4、LUCENE 中文词汇分词(WORD SEGMENT)问题总结

5、解剖 LUCENE 的总体架构

web 前端中文站点评:

通过对以上几篇有关 Lucene 的学习,我觉得可以对 Lucene 有了更深的理解,这样才能少走弯路,大家有什么想法建议也可以分享出来喔~

【注:本文源自网络文章资源,由站长整理发布】


web 前端中文站 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Lucene 安装和应用实战
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址