倒排索引

 

**全文检索(Full-text Search)**:即先建立索引,再对索引进行搜索(倒排索引)。索引是从非结构化数据中提取出之后重新组织的信息。

![lucene的一般过程.png](https://segmentfault.com/img/remote/1460000021695249)

全文检索大体分两个过程,**索引创建(Indexing)和搜索索引(Search)**。

- 索引创建:将现实世界中所有的结构化和非结构化数据提取信息,创建索引的过程。
- 搜索索引:就是得到用户的查询请求,搜索创建的索引,然后返回结果的过程。

## 索引创建

全文检索的索引创建过程一般有以下几步:

#### 第一步:一些要索引的原文档(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.

#### 第二步:将原文档传给分词组件(Tokenizer)。

**将文档分成一个一个单独的单词。去除标点符号。去除停词(Stop word)。

1. **变为小写(Lowercase)。**
2. **将单词缩减为词根形式,如"cars"到"car"等。这种操作称为:stemming。** “缩减 采取某种固定的算法来做这种缩减,如去除“s”,去除“ing”加“e”,将“ational”变为“ate”,将“tional”变为“tion”。
3. **将单词转变为词根形式,如"drove"到"drive"等。这种操作称为:lemmatization。**“转变”的方式 采用保存某种字典的方式做这种转变。比如字典中有“driving”到“drive”,“drove”到“drive”,“am, is, are”到“be”的映射,做转变时,只要查字典就可以了。

## 索引查询

Elasticsearch 执行上面 `match` 查询的步骤是:

1. *检查字段类型* 。

标题 `title` 字段是一个 `string` 类型( `analyzed` )已分析的全文字段,这意味着查询字符串本身也应该被分析。

2. *分析查询字符串* 。

将查询的字符串 `QUICK!` 传入标准分析器中,输出的结果是单个项 `quick` 。因为只有一个单词项,所以 `match` 查询执行的是单个底层 `term` 查询。

3. *查找匹配文档* 。

用 `term` 查询在倒排索引中查找 `quick` 然后获取一组包含该项的文档,本例的结果是文档:1、2 和 3 。

4. *为每个文档评分* 。

用 `term` 查询计算每个文档相关度评分 `_score` ,这是种将词频(term frequency,即词 `quick` 在相关文档的 `title` 字段中出现的频率)和反向文档频率(inverse document frequency,即词 `quick` 在所有文档的 `title` 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。

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

对于程序员本身来说,这项技术掌握越深越好(掌握越深说明花时间看的越多,tf越大),找工作时越有竞争力。然而对于所有程序员来说,这项技术懂得的人越少越好(懂得的人少df小),找工作越有竞争力

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)是一维

![image-20201219170829715](C:\Users\yuqin03\AppData\Roaming\Typora\typora-user-images\image-20201219170829715.png)

 

https://tech.youzan.com/search-engine1/ ES 索引构建

分级索引:在数据量非常大的情况下,为了保证倒排索引的高效检索效率,任何对数据的更新,并不会实时修改索引,一旦产生碎片,会大大降低检索效率。 既然索引数据不能实时修改,如何保证***的网页能够被索引到呢? 索引分为全量库、日增量库、小时增量库。 当有修改请求发生时,只会操作***级别的索引,例如小时库。 当有查询请求发生时,会同时查询各个级别的索引,将结果合并,得到***的数据 merger:将离线的数据合并到高一级别的索引中去 小时库,一小时一次,合并到天库中去; 天库,一天一次,合并到全量库中去; 这样就保证了小时库和天库的数据量都不会特别大; 如果数据量和并发量更大,还能增加星期库,月库来缓冲。

posted @ 2020-12-23 14:55  打了鸡血的女汉子  阅读(169)  评论(1编辑  收藏  举报