一 全文检索介绍

先建立索引,再对索引进行搜索的过程就叫全文检索

搜索引擎核心:建立倒排索引

二 数据库和 solor搜索引擎对比

1 搜索引擎的索引和 数据库索引区别

原理相通,只是索引结构不同 一个是B+树,一个是倒排索引树

2 各自定位对比

数据库核心是数据存储和事务能力,在大数据量下搜索会很慢

搜索引核心是 专职建立索引使在大数据量下快速搜索, 并根据算法和 数据结构对查询结果进行相关性排序

一个是结构化数据 ,另一个是非结构化数据

三 全文检索流程图

四 创建索引过程

第一步:一些要索引的原文档(Document)。

为了方便说明索引创建过程,这里特意用两个文件为例:

文件一:Students should be allowed to go out with their friends, but not allowed to drink beer.

文件二:My friend Jerry went to school to see his students but found them drunk which is not allowed.

第二步:将原文档进行词法/语法分析 拆成一堆词。

文档拆成一个个词,大小写转换,去掉标点,时态处理等等

“student”,“allow”,“go”,“their”,“friend”,“allow”,“drink”,“beer”,“my”,“friend”,“jerry”,“go”,“school”,“see”,“his”,“student”,“find”,“them”,“drink”,“allow”。 

第三步:将得到的词(Term)传给索引组件(Indexer)。

索引 组件(Indexer)主要做以下几件事情:

1. 利用得到的词(Term)创建一个字典。

在我们的例子中字典如下:

Term

Document ID

student

1

allow

1

go

1

their

1

friend

1

allow

1

drink

1

beer

1

my

2

friend

2

jerry

2

go

2

school

2

see

2

his

2

student

2

find

2

them

2

drink

2

allow

2

 

2. 对字典按字母顺序进行排序。

 

Term

Document ID

allow

1

allow

1

allow

2

beer

1

drink

1

drink

2

find

2

friend

1

friend

2

go

1

go

2

his

2

jerry

2

my

2

school

2

see

2

student

1

student

2

their

1

them

2

 

3. 合并相同的词(Term) 成为文档倒排(Posting List) 链表。

全文搜索引擎java集成 全文搜索引擎工作原理_搜索

 

 

在此表中,有几个定义:

  • Document Frequency 即文档频次,表示总共有多少文件包含此词(Term)。 
  • Frequency 即词频率,表示此文件中包含了几个此词(Term)。 

至此索引创建完毕,下一步搜索过程

五 搜索过程

第一步:用户输入查询语句。

查询语句同我们普通的语言一样,也是有一定语法的。

不同的查询语句有不同的语法,如SQL语句就有一定的语法。

查询语句的语法根据全文检索系统的实现而不同。最基本的有比如:AND, OR, NOT等。

举个例子,用户输入语句:lucene AND learned NOT hadoop。

说明用户想找一个包含lucene和learned然而不包括hadoop的文档。

第二步:对查询语句进行词法分析,语法分析,及语言处理。

由于查询语句有语法,因而也要进行语法分析,语法分析及语言处理。

1. 词法分析主要用来识别单词和关键字。

比如关键字有AND, NOT等。

2. 语法分析主要是根据查询语句的语法规则来进行 或/与/非等逻辑判断。

3. 语言处理同索引过程中的语言处理几乎相同。

如learned变成learn等。

经过第二步,我们得到一棵经过语言处理的语法树。

全文搜索引擎java集成 全文搜索引擎工作原理_查询语句_02

 

 

 

第三步:搜索索引,得到符合语法树的文档。

此步骤有分几小步:

  1. 首先,在反向索引表中,分别找出包含lucene,learn,hadoop的文档链表。
  2. 其次,对包含lucene,learn的链表进行合并操作,得到既包含lucene又包含learn的文档链表。
  3. 然后,将此链表与hadoop的文档链表进行差操作,去除包含hadoop的文档,从而得到既包含lucene又包含learn而且不包含hadoop的文档链表。
  4. 此文档链表就是我们要找的文档。 

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

1. 计算权重(Term weight)的过程。

影响一个词(Term)在一篇文档中的重要性主要有两个因素:

  • Term Frequency (tf):即此Term在此文档中出现了多少次。tf 越大说明越重要。 
  • Document Frequency (df):即有多少文档包含次Term。df 越大说明越不重要。 

权重公式:

 

全文搜索引擎java集成 全文搜索引擎工作原理_搜索_03

全文搜索引擎java集成 全文搜索引擎工作原理_链表_04

 

2. 判断Term之间的关系从而得到文档相关性的过程,也即向量空间模型的算法(VSM)。

我们把文档看作一系列词(Term),每一个词(Term)都有一个权重(Term weight),不同的词(Term)根据自己在文档中的权重来影响文档相关性的打分计算。

于是我们把所有此文档中词(term)的权重(term weight) 看作一个向量。

Document = {term1, term2, …… ,term N}

Document Vector = {weight1, weight2, …… ,weight N}

同样我们把查询语句看作一个简单的文档,也用向量来表示。

Query = {term1, term 2, …… , term N}

Query Vector = {weight1, weight2, …… , weight N}

我们把所有搜索出的文档向量及查询向量放到一个N维空间中,每个词(term)是一维。

如图:

全文搜索引擎java集成 全文搜索引擎工作原理_查询语句_05

 

 

 

我们认为两个向量之间的夹角越小,相关性越大。

相关性打分公式如下:

全文搜索引擎java集成 全文搜索引擎工作原理_查询语句_06

 

举个例子,查询语句有11个Term,共有三篇文档搜索出来。其中各自的权重(Term weight),如下表格。 

 

t1

t2

t3

t4

t5

t6

t7

t8

t9

t10

t11

D1

0

0

.477

0

.477

.176

0

0

0

.176

0

D2

0

.176

0

.477

0

0

0

0

.954

0

.176

D3

0

.176

0

0

0

.176

0

0

0

.176

.176

Q

0

0

0

0

0

.176

0

0

.477

0

.176

 

于是计算,三篇文档同查询语句的相关性打分分别为:

 

 

全文搜索引擎java集成 全文搜索引擎工作原理_搜索_07

 

全文搜索引擎java集成 全文搜索引擎工作原理_全文搜索引擎java集成_08

 

全文搜索引擎java集成 全文搜索引擎工作原理_搜索_09

 

 

于是文档二相关性最高,先返回,其次是文档一,最后是文档三。

到此为止,我们可以找到我们最想要的文档了。