搜索引擎之索引建立原理

来源:互联网 发布:蓝牙对码软件 编辑:程序博客网 时间:2024/05/22 03:16

 

 

我们假设有这样一张商业信息数据表,我们用什么样的算法和结构(索引技术)可以快速方便实现搜索功能呢?

Sid

Subject

Type

Price

id

Description

PostTime

0

Sell apple

Sale

50

101

We are one of the largest …

2002-10-02

1

Buy Digital Camera

Buy

200

102

Our company mobile-point is situated in the …

2003-02-10

2

Sell dog shoes

Sale

45

103

Dog Shoes Model Number: 02GLPS074 Place of …

2003-12-18

3

Buy Toys And Jewelry

Buy

1000

104

I am interested in items that can be ordered in small …

2003-08-20

(商业信息数据表)

一般我们需要的查询的需求分为下面两类:

a.  希望通过某个关键字找到所需信息(根据关键字来搜索)

b.  希望能够根据type, price, PostTime, id等字段进行检索(单字段信息检索)

1.建立索引                                                             

对于a需求:

我们使用 hashtable来达到快速检索的目的,既将可能用于查询的关键字作为hashtablekey(主键),跟该key有关的记录信息(我们称为TokenInfo)作为key对应的值。主键key来源于用于关键字查询的字段的文本(这些字段一般都要求是文本类型),一般一段文本可以分解出许多key,我们把分解的过程称为分词,分解出来的key称为Token。每一个Token是用于关键字查询的最小单位。TokenInfo一般会记录该Token的所在的文档ID(Doc Number), 所在文本的位置(Prox),在文本中出现的次数(Freq),所在的字段等等。详细结构如下:

 

Token Size

 

Token

DocFreq

DocList(链表)

ProxDelta(文件位置指针)

Token

TokenInfo

TokenInfo

Token

TokenInfo

 

… …

 

Doc Number

Token Freq

Field Bit

下一个节点内容

Token

TokenInfo

(DocList链表)

          

(Token HashTable)

ProxDelta(文件位置指针)

N0

A(0,0)

A(0,1)

A(0,n0-1)

N1

A(1,0)

A(1,1)

A(1,n1-1)

… …

1doc中该key出现的位置情况

2doc中该key出现的位置情况

… …

(详细的HashTable结构图)

查询的时候我们会用同样的分词算法把用户输入的关键分解为多个Token,每一个Token都去找这个HashTable, 然后将每一个Token查到的结果集进行合并,返回给用户。

 

对于b需求:

一般字段有下面几种类型:TEXT, STRING, ENUM, RANGE, NUMBER, BIT, DATE等。一般我们是将TEXT, STRING, NUMBER类型的字段采用上述HashTable的方法建立索引,只不过他们的分词方法是不一样的,其中TEXT类型的字段是要进行分词的,STRING类型的字段是不需要分词的,整体作为一个TokenNUMBER类型的字段是将字段转化为数字作为Token,这样可以节省空间;我们将ENUM, RANGE, BIT类型的字段采用BitMap的方法建立索引,下面具体说明BitMap的索引结构(以Type字段为例):

 

Type Value

Bit Map

Buy

… … xxxx xxxx xxxx xxxx 0000 0000 0000 1010

Sale

… … xxxx xxxx xxxx xxxx 0000 0000 0000 0101

… … … …

                                                ^doc#16          ^doc#1

我们再举另外一个例子(用结构体来表示):

假定我们有两个enum类型的字段,每一个类型有几个可能的值,共20条记录:

      Field:

        Country - China, Hong Kong, Japan, Korea, USA

        Color - Blue ,Red, White

      Records:

        China-blue, Hong Kong-blue, Japan-red, China-red, China-white,

            0-0         1-0         2-1      0-1       0-2

        USA-red, Korea-white, China-white, China-white, USA-blue,

          4-1       3-2        0-2        0-2        4-0

        China-red, USA-red, USA-blue, Hong Kong-white, Japan-Red,

           0-1      4-1      4-0         1-2          2-1

        China-red, China-Red, China-BLUE, China-white, China-RED,

           0-1       0-1       0-0         0-2        0-1

      这些数据就可以用下面的结构体来表示:

      SEnumDesc {

        iNumOfFields = 2;

        pField[0] = "Country", pField[1] = "Color";

        pValues[0] = {

          iNumOfValues = 5;

          pVal[0] = "china", pVal[1] = "hong kong", pVal[2] = "japan",

          pVal[3] = "korea", pVal[4] = "usa";

        },

        pValues[1] = {

          iNumOfValues = 3;

          pVal[0] = "blue", pVal[1] = "red", pVal[2] = "white";

        };

      iNumOfDocs = 20;

      pBitmap[0] {

        pMap[0][0] = xxxx xxxx xxxx 1111 1000 0101 1001 1001;     // china

        pMap[1][0] = xxxx xxxx xxxx 0000 0010 0000 0000 0010;     // hong kong

        pMap[2][0] = xxxx xxxx xxxx 0000 0100 0000 0000 0100;     // japan

        pMap[3][0] = xxxx xxxx xxxx 0000 0000 0000 0100 0000;     // korea

        pMap[4][0] = xxxx xxxx xxxx 0000 0001 1010 0010 0000;     // usa

        //                        ^doc#20                ^doc#1

      }

      pBitmap[1] {

        pMap[0][0] = xxxx xxxx xxxx 0010 0001 0010 0000 0011;     // blue

        pMap[1][0] = xxxx xxxx xxxx 1001 1100 1100 0010 1100;     // red

        pMap[2][0] = xxxx xxxx xxxx 0100 0010 0001 1101 0000;     // white

//                        ^doc#20                ^doc#1

      }

如果一个字段是Range类型的,或者搜索的时候是要根据一个范围来查找的,比如说price字段,每一条记录都一个价格值,但是搜索的时候我们一般是根据一个价格范围来查找,对于这样的字段我们建立索引的时候也是采用BitMap结构,既先自己定义几个范围,一个记录该字段的值属于哪个范围,我们就将位置上设1。以price字段为例。

 

Range

Bit Map

<50

… … xxxx xxxx xxxx xxxx 0000 0000 0000 0100

[50,100)

… … xxxx xxxx xxxx xxxx 0000 0000 0000 0001

[100,500)

… … xxxx xxxx xxxx xxxx 0000 0000 0000 0010

>=500

… … xxxx xxxx xxxx xxxx 0000 0000 0000 1000

                                               ^doc#16          ^doc#1

       对于Bit类型的字段同样也是采用BitMap的结构,这里就不在阐述了。BitMap结构的好处是节省空间,结果集合逻辑运算简单快速,但并不是所有Enum类型的字段都采用BitMap结构,当枚举值大于32个的时候,采用BitMap就不方便了,这个时候我们会采用HashTable的结构来建立索引。

 

原创粉丝点击