Lucene.Net 2.3.1开发介绍 —— 三、索引(一)

原文:Lucene.Net 2.3.1开发介绍 —— 三、索引(一)

在说索引之前,先说说索引是什么?为什么要索引?怎么索引?

先想想看,假如现在有一个文本,我们会怎么去搜索。比如,有一个string = "abcdefghijklmnopqrstuvwxyz",这都是26个字母。现在要看看里面是不是有a,用IndexOf就可以很方便实现。现在数据量大了,在数据库里已经有100多条数据了,当然,利用数据库提供的操作方法,也可以很方便的查找。而这里先抛开数据库,把这100多条记录放到N个文本文件中,现在要在里面搜索含有“Lucene”这个词的记录,那怎么办呢?如果只简单地使用逐个文件逐字扫描的话,那和用Windows内置的搜索,搜索一张图片名,或者文本没什么分别。那么每次搜索都会需要大量时间,而google和baidu为什么能做到那么快呢?既然刚才我们是抛开数据库,是不是使用了数据库就能实现呢?从我长期使用的经验来看,数据库肯定是不行的(这里指关系型数据库,要是出某些专门为搜索做的数据库那就另外说了。)。什么东西在搜索的时候足够快呢?在C#类型里就有这么几个,比如Hashtable,Dictionary。做搜索引擎是否也可以应用这样的思想?显然是可以的!有很多东西在微观(这里指一小个算法或者一个小型的数据结构应用)和宏观(这里指框架级或者系统级)上名字不一样,但是都有很多的相似性和可比性,无疑Lucene.Net就是这样一个框架,实现了Hashtable更加宏观的现象!当然也是有很多差别。

Lucene.Net用的就是倒排索引的一种数据结构,记得以前看过一篇文章,讲在面向对象时代,数据结构的作用被减弱了,我觉得这个观点至少在Lucene.Net上必须被抛弃。回答原先的问题,什么是索引?纵观搜索引擎的发展历史,早期的搜索引擎都是基于关键字和目录的,而现在已经转变成全文搜索。若要问什么是索引,那就是你有一本书,你看到了第八页是写一个故事,你用一张纸把故事名称记录下来,那就是索引。书的目录,是的页数,书的编号等等都可以算是索引。Lucene.Net用的就是倒排索引,那什么是倒排索引?那就是对一段文本就行分析,按分析结果,把分析得到的关键字建立索引。比如“我在用Lucene.Net。”,用StandardAnalyzer分词器索引后,就会存储“我”,“在”,“用”,“Lucene”,“.”,“Net”,“。”这些词,也就是说,索引是以词为单位存储的。同时记录下了这些词出现在了哪个文档中,以及出现的位置和频率。很像在数据库里做冗余不是吗?这些需要计算的数据都已经记录下来,直接读取就可以看了。从理论上说,在定义使用M种语言的情况下,出现词的数量总是有限的。从这里也可以看出分词是如此重要,因为分词让N个字连成了一个整体,用这个整体中的任何一个字是查不到这个整体的,除非以牺牲速度为代价。以前说google水土不服,就是因为google在中文分词上不如baidu,但是这个差距在缩小。

而另外一个问题,为什么要索引,也就不难解答了。至于怎么索引,这又是一个很长的故事了。

1、逻辑存储结构

词在倒排索引中是最小的单位,在Lucene.Net中衡量单位是Term,由N个Term构成了Filed,而又有N个Filed组成了Document,N个Document又会组成一个Segment,N个Segment会被写到Lucene.Net的文件系统。文件系统留到后面再讲,因为Lucene.Net自己实现了自己的文件系统,而这个系统的最小单位由3个文件组成,可以放到一个目录下,也可以放到内存中。总的来说Lucene.Net的文件系统可以理解为一个个的文件,在Windows下就是一个目录,里面包含了三个文件,但是从Lucene.Net的逻辑上来说,这就是一个文件。然后文件里的文本分词N个章节,那就是Segment,每个段落又会有N个段落(Document),段落里的每句话就是Filed,而Term就是每个字。和我们处理习惯很像不是吗?而其中最重要的就是Term,其他都是为它排版用的。

而这个索引相对于分词,也可以用另外一个类来衡量,那就是——Token,是不是很熟悉?Term和Token的文本是一样的,只是记录的关于这个文本的属性不一样。

前面写到了两次写入索引的操作,代码大同小异。都是先建立一个分词器,然后把分词器交给IndexWriter。接着创建N个Document,往Docuemnt里填充Field,再把Document交给IndexWriter操作,就完成了整个索引过程。关于Segment的处理被黑箱子掉了,而Term的处理也仅仅能从分词器看到个大概。

(PS:不行了,睡觉了。ZZzzzzz~~)

时间: 2024-10-18 02:51:37

Lucene.Net 2.3.1开发介绍 —— 三、索引(一)的相关文章

Lucene.Net 2.3.1开发介绍 —— 三、索引(五)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(五) 话接上篇,继续来说权重对排序的影响.从上面的4个测试,只能说是有个直观的理解了.“哦,是!调整权重是能影响排序了,但是好像没办法来分析到底怎么调啊!”.似乎是这样,现在需要把问题放大,加大索引的内容.到博客园新闻区,用zzk找了4篇内容包含“测试”的文章.代码变成 2.1.5 代码2.1.5  1using System;  2using System.Collections.Generic;  3using Lucene.N

Lucene.Net 2.3.1开发介绍 —— 三、索引(四)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响 搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个这个结果是怎么得出来的?这个顺序又是怎么排的呢?这两个问题不是本节讨论的重点,但是这两个问题却关系到本节要讨论的,索引对结果的影响问题.在不使用字段排序的情况下,Lucene.Net默认是按文档的得分来排序的,这个公式看着很复杂,感觉像是大学时高数书上的那些个公式,其实说清楚了也简单. 关于文档排序

Lucene.Net 2.3.1开发介绍 —— 三、索引(七)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(七) 5.IndexWriter 索引这部分最后讲的是IndexWriter.如果说前面提到的都是数据的结构,那么IndexWriter就是业务的封装.无论述Document,Field还是看不见的Segment,Term都是对数据存储逻辑的抽象,IndexWriter包装了操作的过程. 当然,这里不会讨论IndexWriter的每个细节,这里主要介绍IndexWriter的常用法和实际使用中遇到的部署问题. 5.1 IndexWr

Lucene.Net 2.3.1开发介绍 —— 三、索引(六)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(六) 2.2 Field的Boost 如果说Document的Boost是一条线,那么Field的Boost则是一个点.怎么理解这个点呢?设置Document的Boost会影响所有字段.在搜索的过程中,一般至少会搜索两个Field,比如同时搜索标题和内容.而Document的Boost将同时影响标题和内容的搜索得分,但是设置Field的Boost则不会有那么大的影响,Field的Boost只会影响一个点.那这个点有什么用呢? 现在来

Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的基础,Directory是索引建立中或者建立好存储的介质,Document和Field类是逻辑结构的核心,IndexWriter是操作的核心.其他类的使用都被隐藏掉了,这也是为什么Lucene.Net使用这么方便的原因. 2.1 Analyzer 前面已经对Analyzer进行了很详细的讲解,Ana

Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(三) 3.Field配置所产生的效果 索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是Field,接下来看看Field的各项设置都会有什么样的效果. 代码 3.1 Code 1/**//// <summary> 2/// 索引数据 3/// </summary> 4private void Index() 5{ 6    Analyzer analyzer = new S

Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)

原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了. 代码 4.3.4.1 Analyzer analyzer = new StandardAnalyzer(); QueryParser parser = new QueryParser("title", analyzer); Query query = parser.Parse(@":"); Console.Write

Lucene.Net 2.3.1开发介绍 —— 二、分词(三)

原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(三) 1.3 分词器结构 1.3.1 分词器整体结构 从1.2节的分析,终于做到了管中窥豹,现在在Lucene.Net项目中添加一个类关系图,把TokenStream和他的儿孙们统统拉上去,就能比较好的把握他们之间的关系. 图 1.3.1.1 如图1.3.1.1 就是他们的类关系图.看出如果要做一个分词器,最短的路,就是继承第二代,成为第三代.然后再写一个Analyzer的子类,专门用来做新分词器的适配器就好了.转换器.  呵呵,写

Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)

原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此,搜索和索引一般是分开部署.简单地说,就是一个应用程序(桌面程序)来索引,一个WEB程序来实现搜索.当然,为了测试的时候简单,这里还是使用NUnit的方式运行.搜索讲完后,将会简单介绍单机搜索引擎如何部署. 4.1 搜索与什么有关 搜索与什么有关呢?即使没有看过前面的文章,那么现在来随便猜一猜. 首