在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类。其中Analyzer是索引建立的基础,Directory是索引建立中或者建立好存储的介质,Document和Field类是逻辑结构的核心,IndexWriter是操作的核心。其他类的使用都被隐藏掉了,这也是为什么Lucene.Net使用这么方便的原因。
2.1 Analyzer
前面已经对Analyzer进行了很详细的讲解,Analyzer将会把一段文本分析称一个个Token。这些Token如何被IndexWriter使用,这里牵涉到一个很重要的类,那就是DocumentsWriter。这个类非常关键,可以说是索引部分最核心的类,IndexWriter只是它的一个包装。这里主要介绍应用,所以就不做太详细的介绍。Token在DocumentsWriter类中,通过DocumentsWriter的最重要的方法——InvertField——推送到了Field中。这样就完成了分词添加到逻辑结构的过程。
2.2 Directory
严格来说,Directory并不专属于索引,它代表的是Lucene.Net的存储介质,它表示了索引具体存放到什么地方。在前面的两个示例中似乎没有使用到它,那是因为你传入的路径,会自动转换成Directory。Directory有两个子类,分别是RAMDirectory——代表索引存放到内存中,和FSDirectory——代表索引存放到硬盘。在使用FSDirectory存放到硬盘的过程中,还是会调用RAMDirectory。IndexWriter会把建立的索引先放到RAMDirectory,然后到一定的条件,才将这些数据写入硬盘。
2.3 IndexWriter
IndexWriter是索引中负责操作的核心,它负责把索引文件写入存储介质,是控制逻辑存储转换为物理存储的纽带。
IndexWriter共有10个可以使用的构造函数,但是他们的参数类型比较少。一共有以下几种:
(1)、Directory d;
(2)、Analyzer a;
(3)、bool create;
(4)、FileInfo path;
(5)、string path;
(6)、bool autoCommit;
(7)、IndexDeletionPolicy deletionPolicy;
其中6,7不常用。而FileInfo path和string path最终都会构造成Directory,又因为这两种路径都是磁盘的路径,所以构造出来的Directory一定是FSDrectory。bool create表示是否是创建,否则是增量更新,默认状态是false。bool autoCommit不常用,是用来指定是否当索引在close状态下才更新的,如果是false,则需要在close状态下更新。IndexDeletionPolicy deletionPolicy则是指定是否对以前的更新进行移除,它能表示为两个值,KeepOnlyLastCommitDeletionPolicy和SnapshotDeletionPolicy,默认状态下是,KeepOnlyLastCommitDeletionPolicy。
2.4 Document
Document就是一条虚拟记录,可以理解为数据里的一行。正是有了它,才使我们可以很方便并且易于理解地操作索引文件。它一般记录了需要用到的一个文档的属性,当然,这需要和Field联合使用。
2.5 Field
Field类就是数据库里的一列。一个文档有标题,内容,作者,创建时间这四个属性的话,那么就需要四个Field保存这些属性,然后把四个Field加入到Document中,就有了一行记录。在查询的时候,无论查那个列,总能得到一整行记录,是不是和数据库很相似?
Field本身具有一些属性,就和数据库里的列一样。它的属性通过它的三个内嵌类设置,其实这个地方完全可以用枚举,但是很遗憾的是Java里面没有枚举,所以移植过来也没有转换为枚举。
Field的构造函数也比较多,有7个之多。其中Store,Index和TermVector是通过内部类指定的。
(1)、Store 有三个选项,Field.Store.COMPRESS表示被压缩存储;Field.Store.YES表示储存;Field.Store.NO表示不被存储。
(2)、Index的选项有四个,Field.Index.NO表示不建立索引;Field.Index.TOKENIZED表示分词后索引;Index.NO_NORMS表示值存储内容;Field.Index.UN_TOKENIZED表示不分词索引。
(3)、TermVector这个参数也不常用,它有五个选项。Field.TermVector.NO表示不索引Token的位置属性;Field.TermVector.WITH_OFFSETS表示额外索引Token的结束点;Field.TermVector.WITH_POSITIONS表示额外索引Token的当前位置;Field.TermVector.WITH_POSITIONS_OFFSETS表示额外索引Token的当前和结束位置;Field.TermVector.YES则表示存储向量。
2.6 索引核心类工作流程
图 2.6.1
如图2.6.1表示了数据在Lucene.Net索引过程处理的整个流程。注意,这个流程图中,分词器并不直接产生Field对象,在实例中Analyzer是被赋予IndexWriter实例的,等等执行添加文档操作的时候,IndexWriter才会真正地调用分词器生成Field需要的数据(在DocumentWriter类中)。上图只是反映了数据是如何流动的,并不是真实的调用过程。
2.1 Analyzer
前面已经对Analyzer进行了很详细的讲解,Analyzer将会把一段文本分析称一个个Token。这些Token如何被IndexWriter使用,这里牵涉到一个很重要的类,那就是DocumentsWriter。这个类非常关键,可以说是索引部分最核心的类,IndexWriter只是它的一个包装。这里主要介绍应用,所以就不做太详细的介绍。Token在DocumentsWriter类中,通过DocumentsWriter的最重要的方法——InvertField——推送到了Field中。这样就完成了分词添加到逻辑结构的过程。
2.2 Directory
严格来说,Directory并不专属于索引,它代表的是Lucene.Net的存储介质,它表示了索引具体存放到什么地方。在前面的两个示例中似乎没有使用到它,那是因为你传入的路径,会自动转换成Directory。Directory有两个子类,分别是RAMDirectory——代表索引存放到内存中,和FSDirectory——代表索引存放到硬盘。在使用FSDirectory存放到硬盘的过程中,还是会调用RAMDirectory。IndexWriter会把建立的索引先放到RAMDirectory,然后到一定的条件,才将这些数据写入硬盘。
2.3 IndexWriter
IndexWriter是索引中负责操作的核心,它负责把索引文件写入存储介质,是控制逻辑存储转换为物理存储的纽带。
IndexWriter共有10个可以使用的构造函数,但是他们的参数类型比较少。一共有以下几种:
(1)、Directory d;
(2)、Analyzer a;
(3)、bool create;
(4)、FileInfo path;
(5)、string path;
(6)、bool autoCommit;
(7)、IndexDeletionPolicy deletionPolicy;
其中6,7不常用。而FileInfo path和string path最终都会构造成Directory,又因为这两种路径都是磁盘的路径,所以构造出来的Directory一定是FSDrectory。bool create表示是否是创建,否则是增量更新,默认状态是false。bool autoCommit不常用,是用来指定是否当索引在close状态下才更新的,如果是false,则需要在close状态下更新。IndexDeletionPolicy deletionPolicy则是指定是否对以前的更新进行移除,它能表示为两个值,KeepOnlyLastCommitDeletionPolicy和SnapshotDeletionPolicy,默认状态下是,KeepOnlyLastCommitDeletionPolicy。
2.4 Document
Document就是一条虚拟记录,可以理解为数据里的一行。正是有了它,才使我们可以很方便并且易于理解地操作索引文件。它一般记录了需要用到的一个文档的属性,当然,这需要和Field联合使用。
2.5 Field
Field类就是数据库里的一列。一个文档有标题,内容,作者,创建时间这四个属性的话,那么就需要四个Field保存这些属性,然后把四个Field加入到Document中,就有了一行记录。在查询的时候,无论查那个列,总能得到一整行记录,是不是和数据库很相似?
Field本身具有一些属性,就和数据库里的列一样。它的属性通过它的三个内嵌类设置,其实这个地方完全可以用枚举,但是很遗憾的是Java里面没有枚举,所以移植过来也没有转换为枚举。
Field的构造函数也比较多,有7个之多。其中Store,Index和TermVector是通过内部类指定的。
(1)、Store 有三个选项,Field.Store.COMPRESS表示被压缩存储;Field.Store.YES表示储存;Field.Store.NO表示不被存储。
(2)、Index的选项有四个,Field.Index.NO表示不建立索引;Field.Index.TOKENIZED表示分词后索引;Index.NO_NORMS表示值存储内容;Field.Index.UN_TOKENIZED表示不分词索引。
(3)、TermVector这个参数也不常用,它有五个选项。Field.TermVector.NO表示不索引Token的位置属性;Field.TermVector.WITH_OFFSETS表示额外索引Token的结束点;Field.TermVector.WITH_POSITIONS表示额外索引Token的当前位置;Field.TermVector.WITH_POSITIONS_OFFSETS表示额外索引Token的当前和结束位置;Field.TermVector.YES则表示存储向量。
2.6 索引核心类工作流程
图 2.6.1
如图2.6.1表示了数据在Lucene.Net索引过程处理的整个流程。注意,这个流程图中,分词器并不直接产生Field对象,在实例中Analyzer是被赋予IndexWriter实例的,等等执行添加文档操作的时候,IndexWriter才会真正地调用分词器生成Field需要的数据(在DocumentWriter类中)。上图只是反映了数据是如何流动的,并不是真实的调用过程。