目前自己的工作是跟搜索引擎相关的,之前博客 也写了一部分搜索引擎相关的,但“纸上得来终觉浅,绝知此事要躬行”,想更进一步对搜索引擎有更深的理解,可以尝试着自己动手去做一个搜索引擎。 如果是自己要做一个搜索引擎,那其实得先要从离线去做。可以先从最原始的搜索引擎功能开始,先不考虑ANN这种。
index服务:计算倒排索引的相关性的服务
单机下我们是无法装载完全部索引的,所以这就带来一个问题? 我们是按term切分,还是按照文档切分
- 按term切分
- 优势:
- 不需要全扇出,能够有效减少indexer
- 劣势:
- 对于高频的term,始终会出现单机上无法存储完整的情况,对于这种情况,横向扩展复杂,也容易出现数据热点
- 并且对于高频的term,长度过长,index服务计算的长度不可控
- 按文档切分【目前主流搜索引擎一般都是按照doc切分】
- 优势:
- 可以支持横向扩展
- 劣势:
- 每次请求都是全扇出,要请求到所有的索引服务
搜索引擎一般还需要关心数据的抓取
离线建库其实需要对内容做语义理解,比如如何做切词,比较通用的切词方案,同时也支持用户自己进行语义理解,直接建库
我们需要考虑我们倒排的数据结构如何存储的问题,这块设计上会跟ES的设计比较类似
其实正排的数据,就是kv了,我们从倒排中拉链出来的正排,会放到这里来存储。而这块的底层数据的话,我们会采用rocksdb进行存储。 因为目前官方的原生支持里面中只有c++和java版本,所以目前短期内先使用cgo进行支持
类似于ES中,是否只有一个通用的模型去做语义理解 最常见的语义理解工具就是切词工具
而其中其实还应该包括一些杂质词去除(比如去除特殊符号、的这种无意义的词),归一化【沪天气归一化成上海天气】,纠错(刘得华纠错成刘德华) 这种其实有编辑距离的应用,我们能够通过计算,得到两个词的编辑距离
而类似于ANN这种,其实是通过数据挖掘 + 人工标注等方式,得到词语之间的关系
思考各个触发模型 + 解析模型的数据结构,ES中的数据结构是什么样【值得思考与探索】
现代分词方法大致有三种: 1、基于字符串配置的分词方法 2、基于理解的分词方法 3、基于统计的分词方法
通过语义理解之后,如何避免全扇出,其实可以通过召回模型,去指定相关的资源号的方式? 多个ES + 多个召回模型,是否也是类似于资源号的扩展方式 ES中是否每次请求都是全扇出?
todo
我们如何去组织相关项目的结构,其实这个一直就不是一个非常容易的问题