这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
项目目标
- 使用go语言实现
- 支持全文搜索
- 类似电商的搜索引擎,支持多字段的检索,不仅仅是文本的全文索引,还包括过滤功能。
- 支持相关性排序
- 支持集群部署
- 支持根据条目分类展示
- 支持分布式的集群部署,能动态的扩缩容
基本概念
文档:搜索引擎的基本数据单元,比如一张网页,一个商品,多个文档合在一起就是一个搜索引擎的完整数据,类似于数据库中的一行数据倒排索引,正排索引,存储在搜索引擎内部的数据结构,也是搜索引擎最底层的数据结构。字段,每个文档可能有多个字段,比如一篇文章有标题,作者,摘要,详情,发布时间的,这些东西虽然在一个文档中,但是搜索的时候需要区别对待。索引,多个文档通过生成了一堆倒排正排索引,我们把这些倒排正排索引的集合叫索引,如果后面提到索引就是指正排和倒排索引的集合,索引也可以理解为数据库中的表。
接下来讲讲搜索引擎最重要的两个部分,倒排索引,正排索引
倒排索引
先从最简单的倒排索引结构讲起——map
构建倒排索引目的是我们希望可以通过它快速找到包含某些内容的文档。所以构建倒排索引首先我们需要将文档中需要构建倒排的字段内容进行分词。比方说,“今天中午吃什么”,分词后变成今天、中午、吃、什么。map的key就是分词后的结果,叫做term。value保存的就是包含这个分词的文档id集合,可以叫做倒排链。这里就简要介绍一下思路,具体的设计这篇文章讲不完,可能还要再单独写入一篇文章讲倒排索引。
正排索引
我的理解是功能类似于数据库中的索引,主要是为了加快查询速度,以及用于实现过滤,区间,条件搜索,汇总。,比方说,你对价格构建了正排索引,可以通过倒排快速找到符合某个价格区间内文档数据或id。因为B+树本身就是有序的,而且叶子节点通过指针连在一下,可以很方便地进行区间查找。所以我们想采用B+树来实现正排索引。
总结
这篇文章主要讲解了一些搜索引擎的核心概念,以及倒排正排的构建的基本思路,没有深入讲细节方面的实现。实际上,还有很多问题需要解决,比如,文档量大的情况下,倒排索引的倒排链部分,会占用大量的空间,内存可能都存放不下,可搜索引擎要实现快速的全文查找,倒排索引还是放入内存比较好,如何压缩倒排索引的倒排链,还需要思考。整体的项目架构也还没定论,多线程下如何解决读写冲突问题,删除操作直接删除文档代价太大的问题等一系列问题没有解决。