搜索常见问题

1、倒排索引

讲倒排索引之前先讲正牌索引,意思就是我们的所有文档都有唯一一个文档id,根据文档里的内容算出每个文档中关键字的内容和次数,类似于通过key去找value的形式,如果正牌索引,我们每次寻找关键字查询,就得搜索所有的文档去看是否有这个关键字,这样查询效率太慢了。
于是有了倒排索引,是通过关键字去查文档,我们建立一个索引库,里面的key是关键字,value是每个文档的id,倒排在构建索引的时候较为耗时且维护成本较高,但是搜索耗时短,所以我们可以定时去更新索引库。
查询出来的文档可以通过一个打分算法来进行排序。

1.1组成

详细介绍:https://www.cnblogs.com/zlslch/p/6440114.html

索引系统除了记录文档编号和单词频率信息外,额外记载了两类信息,即每个单词对应的“文档频率信息”(对应图6的第三栏)以及在倒排列表中记录单词在某个文档出现的位置信息。

 以单词“拉斯”为例,其单词编号为8,文档频率为2,代表整个文档集合中有两个文档包含这个单词,对应的倒排列表为:{(3;1;<4>),(5;1;<4>)},其含义为在文档3和文档5出现过这个单词,单词频率都为1,单词“拉斯”在两个文档中的出现位置都是4,即文档中第四个单词是“拉斯”。

有了这个索引系统,搜索引擎可以很方便地响应用户的查询,比如用户输入查询词“Facebook”,搜索系统查找倒排索引,从中可以读出包含这个单词的文档,这些文档就是提供给用户的搜索结果,而利用单词频率信息、文档频率信息即可以对这些候选搜索结果进行排序,计算文档和查询的相似性,按照相似性得分由高到低排序输出,此即为搜索系统的部分内部流程

1.2 构建

单词词表是在根据term查找对应倒排链表的过程,即持有term检索对应term的倒排链表。

一般有哈希表+链表、B+数+链表。

对于倒排链表遍历查找,数组效率更高,因为CPU处理时会先从缓存中查找数据,如果没有再从内存中查找。相比较链表的跳跃地址、数组的连续地址往往能命中缓存。所以一般倒排链表中的docid都是数组形式。可以通过bolck进行分块,block间使用链表,block内使用数组

对于构建时的分片有两种形式:

按文档分片。对于一个term的长索引,切分成多个小索引,索引内使用本地docid。

按term分片。主要适用于冷门数据,将term的索引单独分配到节点。缺点是需要在查询段配置term与节点的对应关系。当有该term时才会到对应节点查询。

2、增量索引

全量数据定期重新构建。

增量索引快速更新。适用双buff机制。

增量步骤:

  • 1:indexer从索引2切换到索引1

  • 2:更新索引2

  • 3:indexer从索引1切回到索引2

  • 4:更新索引1

这样可以保证实时的动态更新,但是它的缺点也很明显:必须使用2倍索引大小的内存,机器成本比较高

因此,一般采用全量索引+增量索引的形式。

全量索引服务用来查询截止到某一个日期的全部文档,增量索引服务使用双buffer设计方案查询最近一段时间(可能是小时级或者分钟级)内实时更新的文档内容,然后定期(每天、每周、每月一次)把最近一段时间更新的文档追加在全量索引中。这样做的好处就在于只有少量近期更新文档的查询需要使用双倍内存,机器成本降低。需要注意的一点是,用这种方式建立增量索引时,必须更新全局word的df信息,对于发现的新词还需为其添加全局唯一id,这些信息统统要更新到线上正在运行的全量索引服务。

热更新时可以采用节点内分片的形式,按片进行热更新,减少热更新需要预留的资源。
参考:https://blog.csdn.net/weixin_29173299/article/details/112765964

3、删除doc

 4、faiss 

Faiss是Facebook AI团队开源的针对聚类和相似性搜索库,为稠密向量提供高效相似度搜索和聚类,支持十亿级别向量的搜索,是目前最为成熟的近似近邻搜索库。

 

参考:faiss及PQ、IVF原理

PQ、IVF算法原理

【Faiss】PQ和IVF介绍

参考:

  1. 58搜索引擎架构
  2. 微信搜一搜
posted @ 2022-03-12 23:15  鸭子船长  阅读(56)  评论(0编辑  收藏  举报