Lucene实现索引和查询(3)

建立索引:搜索引擎的索引其实就是实现“单词-文档矩阵”的具体数据结构。也是进行全文检索的第一步,lucene提供IndexWriter类进行索引的管理,主要包括add()、delete()、update()。还有对权值的设定,通过不同索引权值的设定,可以在搜索的时候根据相关性大小进行返回。

进行搜索:原本的直接搜索是针对文档进行顺序检索,在建立索引之后,可以通过对索引的查找以找到索引词在文档中出现的位置,然后返回索引项所对的文档中的位置和词。Lucene提供IndexSearcher类进行对文档的检索,检索形式主要分为两类,第一类是Term,针对单个词项的检索;第二类是Parser,可以自定义构造检索表达式,有较多的检索形式,具体的方法会在之后进行实现的演示。

4.1 实验环境

本PC机采用windows 10x64系统,8G内存,256G固态硬盘。开发环境为Myeclipse 10,jdk版本为1.8。在实验过程中,因为部分语法的转变,若干Class采用1.6版本实现。

4.2 建立索引

建立索引库就是往索引库添加一条条索引记录,Lucene为添加一条索引记录提供了接口,添加索引。

主要用到了“写索引器”、“文档”、“域”这3 个类。要建立索引,首先要构造一个Document 文档对象,确定Document的各个域,这类似于关系型数据库中表结构的建立,Document相当于表中的一个记录行,域相当于一行中的列,在Lucene 中针对不同域的属性和数据输出的需求,对域还可以选择不同的索引/存储字段规则,在本实验中,文件名fileName、文件路径fullPath和文本内容content作为Document 的域。

IndexWriter 负责接收新加入的文档,并写入索引库中。在创建“写索引器”IndexWriter 时需要指定所使用的语言分析器。建立索引分为两个类别,第一:不加权索引;第二:加权索引。

 

public Indexer(String indexDir)throws Exception{ Directory dir=FSDirectory.open(Paths.get(indexDir)); Analyzer analyzer=new StandardAnalyzer(); // 标准分词器 //SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(); IndexWriterConfig iwc=new IndexWriterConfig(analyzer); writer=new IndexWriter(dir, iwc); }

设置索引字段,Store表示是否对索引内容存储:fileName和fullPath占用内存较少可以进行存储,以方便查询返回。

 

private Document getDocument(File f)throws Exception { Document doc=new Document(); doc.add(new TextField("contents", new FileReader(f))); doc.add(new TextField("fileName", f.getName(),Store.YES)); doc.add(new TextField("fullPath",f.getCanonicalPath(),Store.YES));//路径索引 return doc; }

执行主代码后结果如图:设计在索引某个文件的时候返回文件“索引文件:+文件路径”,且计算输出索引全部文件花费的时间。

Lucene实现索引和查询

4.3 对索引的删除和修改

一般对数据库的操作包括CRUD(增加、删除、更改、查询),增加就是对索引项的选择和建立,查询作为较为核心的功能会在之后展开论述,这里主要记录一下在删除、更新索引时用到的方法。

删除分为两种类型,包括普通的删除和彻底删除,因为索引的删除影响到整个数据库,而且对于大型的系统而言,删除索引意味着对系统的底层进行更改,耗时耗力而且无法返回,前面索引的时候看到建立索引后生成若干小文件,当进行查找的时候会将各个文件进行合并然后查找。普通删除仅仅是对之前建立的索引做个简单的标记,致使无法进行查找返回。彻底删除则是对索引进行销毁,无法撤销。以删除索引项“id”为1的索引为例:

普通的删除(在合并前删除):

writer.deleteDocuments(new Term("id","1")); writer.commit();

彻底的删除(在合并后删除):

writer.deleteDocuments(new Term("id","1")); writer.forceMergeDeletes(); // 强制删除 writer.commit();

对索引的修改原理比较简单,就是在原有索引的基础上实现覆盖,实现代码跟上文的增加索引一样,在此不多做阐述。

4.4 对索引的加权

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b267b3b237a20bf36436ddbcf7ac3d25.html