博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene小记(入门篇),索引创建、更新、删除、查找等操作。
阅读量:5741 次
发布时间:2019-06-18

本文共 4453 字,大约阅读时间需要 14 分钟。

hot3.png

    虽然使用Lucene已经有一段时间了,但是仍不敢妄加评论Lucene的好与坏,毕竟目前接触的全文索引技术只有Lucene。而且Lucene并不是真正意义上的引擎,只算的上是Java开发的全文索引工具包。与传统的数据库查询对比,全文索引技术更具有优势。Lucene不仅可以对磁盘文件进行索引,也可以对数据库记录进行索引,并且支持的索引文件格式多种多样(结合其他的文本处理工具)。言归正传,本文将为读者具体讲解Lucene的基本使用,入门级。

    本文Lucene使用的版本为4.0.0

1.    创建索引。

索引创建原理大致分为以下几步:

  • 分词,将原文档传给分词组件进行分词,得到词元。

  • 词元处理,将词元传给语言处理组件进行一些语言处理,例如:变小写,转词根。

  • 索引,对处理后的词元建立词典。例如,词‘中国’出现在ID257的文档中,出现频率分别为153次。

具体实现如下:

    创建索引时需要两个目录,一个是索引文件的存放目录(indexPath),一个是待索引的文件目录(docsPath)。在创建索引时,我们首先要加载或创建索引目录。常用的目录创建方式有两种:

  • 通过RAMDirectory()类创建一个内存目录,内存目录优点是速度快,缺点是程序退出后索引目录数据就会丢失。
RAMDirectory directory = new RAMDirectory();
  • 通过FSDirectory类加载一个文件目录,该方式创建的索引数据保存在磁盘上,不会因为程序的退出而消失。下文都是针对FSDirectory方式来讲解Lucene的基本使用。
Directory dir = FSDirectory.open(new File(indexPath));

    然后通过IndexWriter对象来创建和维护索引。Analyzer为索引分词器,主要是对获取的文本进行分词操作。由于Lucene是由外国人开发的,所以本身对中文的分词效果不是很好。由于中文不像英文那样,词与词之间有明显的分隔符(英文一般以空格区分),所以中文分词在实现上就比英文分词复杂困难的多,而且歧义识别和新词识别一直是中文分词中的难点。

    回归正题,IndexWriterConfig对象用来设置IndexWriter一些初始配置,一旦IndexWriter对象创建完成,改变IndexWriterConfig的配置对已创建的IndexWriter对象不会产生影响。

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_40, analyzer);                 iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);//设置索引维护的方式iwc.setRAMBufferSizeMB(256.0);//设置用来缓冲文档的RAM大小IndexWriter writer = new IndexWriter(dir, iwc);

    接下来需要创建Document文档,并通过IndexWriter对象将文档添加到索引库中。Document文档可以是一个HTML页面,一篇文本文档,一封电子邮件。一个Document可以包含多个FieldField代表文档的属性。此处file为文件对象。

Document doc = new Document();         doc.add(new StringField("path", file.getPath(), Field.Store.YES));doc.add(new TextField("filename", file.getName(), Field.Store.YES));

注意:StringField被索引不被分词,整个值被看作为一个单独的token而被索引。

     TextField既被索引又被分词,但是没有词向量。

    Filed类型还包含LongFieldDoubleFieldIntFiled等,具体的含义请参考官方API

    最后需要将文档添加到索引库中。

writer.addDocument(doc);writer.close();

2.    检索索引。

检索索引的原理大致如下:

  • 对查询语句进行词法分析、语法分析和语言处理。词法分析主要是识别单词和关键字。语法分析主要是根据查询语句的语法规则来形成一颗语法树。语言处理与索引建立过程中语言处理几乎相同。

  • 搜索索引,得到符合语法树的文档

  • 根据得到的文档和查询语句的相关性,对结果进行排序。

具体实现如下:

    检索索引首先要读取索引文档,并建立IndexSearch对象。

IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(indexPath)));IndexSearcher searcher = new IndexSearcher(reader);

    然后需要对查询语句进行分析,Lucene通过Query接口实现类来对查询条件进行分析。Lucene支持单Filed查询、多Field查询、逻辑组合查询、模糊查询、范围查询、通配符查询等。各种查询方式的具体实现本文暂时不讨论。

  1. 单字段查询。

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);QueryParser queryParser = new QueryParser(Version.LUCENE_40, " filename",analyzer) ;queryParser.setDefaultOperator(QueryParser.OR_OPERATOR);//设置默认逻辑‘或’查询Query query = queryParser.parse(condition);
  1. 多字段查询

String[] fields = new String[]{"filename"," path "};Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);//MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(Version.LUCENE_40, fields, analyzer);//Query query = multiFieldQueryParser.parse(condition);BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,                                                     BooleanClause.Occur.MUST};Query query = MultiFieldQueryParser.parse(Version.LUCENE_40, condition, fields, flags, analyzer);

    接下来,通过IndexSearcher对象进行查找。对查询出来的结果可以进行高亮显示关键字,取摘要等处理。    

    TopDocs results = searcher.search(query,10);    ScoreDoc[] hits = results.scoreDocs;    for(ScoreDoc hit:hits){        Document doc = searcher.doc(hit.doc);        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("
", "");        Highlighter highlighter = new Highlighter(formatter, new QueryScorer(query));        Fragmenter fragmenter =new SimpleFragmenter(80);        highlighter.setTextFragmenter(fragmenter);        Information information = new Information();        information.setId(hit.doc);                                         information.setPath(doc.get("path"));        if(highlighter.getBestFragment(analyzer, "filename", doc.get("filename"))==null){            information.setFileName(doc.get("filename"));        }else{            information.setFileName(highlighter.getBestFragment(analyzer, "filename", doc.get("filename")));        }        informations.add(information);    }

3.    更新索引。

Lucene索引的更新为调用IndexWriterupdateDocument方法,该方法接受两个参数,第一个Term词向量,第二个为新增的文档,可以是单个文档,也可以是批量文档。Lucene会先根据Term删除索引库中原有的文档,再向索引库中添加新的documentTerm的第一参数表示要在文档的哪个Field上查找,第二个代表查询关键字。

 writer.updateDocument(new Term("path", file.getPath()), doc);

4.    删除索引。

Lucene索引的删除的可以根据Query对象来删除,也可以根据Term来删除,也可以一次删除全部索引。

//根据Term删除writer.deleteDocuments(new Term("path", file.getPath()));//删除全部索引writer.deleteAll();

 

 

 

 

转载于:https://my.oschina.net/jiangli0502/blog/284478

你可能感兴趣的文章
理解WebKit和Chromium(电子书)
查看>>
爱——无题
查看>>
分布式服务框架原来与实践 读书笔记一
查看>>
【http】post和get请求的区别
查看>>
TFS强制撤销某个工作区的文件签出记录
查看>>
EL表达式无法显示Model中的数据
查看>>
ps6-工具的基础使用
查看>>
灵活运用 SQL SERVER FOR XML PATH
查看>>
es 加磁盘扩容
查看>>
linux下使用过的命令总结(未整理完)
查看>>
时间助理 时之助
查看>>
自定义转场动画
查看>>
英国征召前黑客组建“网络兵团”
查看>>
Silverlight 2.5D RPG游戏“.NET技术”技巧与特效处理:(十二)魔法系统
查看>>
PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)...
查看>>
pyjamas build AJAX apps in Python (like Google did for Java)
查看>>
Java not support java EE1.3
查看>>
LAMP环境搭建1-mysql5.5
查看>>
第三课 Linux目录及文件管理、用户组管理及bash重定向
查看>>
shell 脚本攻略--小试牛刀
查看>>