携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情
本文设计实现的搜索引擎的核心流程基于Go语言的协程(goroutine)与信道(channel)特性实现,分词器、排序器、索引器都设计由多个协程完成,中间的处理结果保存在channel中,避免阻塞情况的发生。通过索引分片,本文设计的搜索引擎支持了并发搜索以降低延迟,索引分片的数量可以由用户自定义,提高了引擎的个性化。由于索引、排序等操作都是在不同分片上并发执行的,因此,最终的结果会在主协程中进行二次归并的操作。总体的设计图如图所示。
上图中描述的搜索引擎设计图主要由四部分协程组成,各部分协程功能如下。
(1)主协程。该协程的主要功能是接收和发送用户请求。
(2)分词器协程。可能有多个,该协程的主要功能是将用户输入的请求进行分词,然后分词器协程会将分词后的结果传递给索引器协程。
(3)索引器协程。可能有多个,该协程的主要功能是将用户输入的文档处理成索引,或者是根据分词器传递过来的关键词,检索到对应的文档。若是第二种情况,索引器协程会将检索到的结果传递到排序器协程。
(4)排序器协程。可能有多个,该协程的主要功能是根据用户自定义的评分规则,或者默认评分规则对从索引器接收到的文档进行赋分与排序的操作,并根据用户的请求是否指定了偏移量来做偏移或截断的操作。
搜索引擎的总体设计中,主要包含两个核心流程。
(1)索引流程。当用户发送一个申请添加文档的请求过来时,根据用户传入的请求参数决定将请求直接传递到索引器协程或先传递给分词器协程处理再传递给索引器协程。索引器会建立关键词到用户传入文档的反向索引,按照本文的设计,反向索引会被存储在内存中。
(2)搜索流程。当主协程接收到用户的查询请求后,首先会检查用户的查询请求参数中是否使用引擎默认的分词器,若不使用,则直接将用户请求参数中传入的关键词通过主协程-索引器信道传递给索引器,若使用,则主协程会将用户请求通过主协程-分词器信道传递给分词器,分词器对用户请求进行分词后,再通过分词器-索引器信道将分词结果传递给索引器。索引器召回每个索引建对应的文档传递给排序器写成对召回结果进行排序操作。最终处理好的结果会由信道传递回主协程并最终由主协程将查询结果返回给用户。