全文搜索
全文搜索
-
Lucene
-
Solr
-
ElasticSearch
db层索引: 非结构化数据,只能全文扫描
因此需要特殊索引:从值反向定位在哪个文档哪行,反向索引
- Parser:解析数据,数据可能是html、pdf、word文档,使用相关的parser解析
- Analysis:分析token,比如有些单词是take、took、taken都是take的不同形式,需要做一个归类
- 然后根据规则,建立索引,这样就可以根据索引查询了
-
keyword => {doc}
-
Ordering:相似度,频率,......
-
index => field
-
更新,增量式维护
IR 信息获取工具
高效交叉索引
query =>
index <-
adapter <-
origin file/web/db/...
衡量指标:
- 精度
- 召回率
- 速度
读入:Analyzer -> Tokenizer -> Tokenfilter -> StopAnalyzer -> Encode/Decode
建索引/存储
Field
- 每个字段对应于在搜索期间根据索引查询或从索引检索的一段数据。
- Keyword:关键字不被分析(就是不会被拆开),而是被索引并逐字存储在索引中。
- UnIndexed:既不分析也不索引,但其值按原样存储在索引中。也就是说一旦假如通过keyword查询到了,要把unindex的部分的内容要带出来,但是这部分不索引。
- UnStored:此字段类型被分析和索引,但不存储在索引中。当然他有一些停用词列表,比如都共有的 词。一般是正文,非常长不应该存在索引里面,非常浪费。
- Text:被分析并被索引,存储到索引里面。这意味着可以针对这种类型的字段进行搜索,但要注意字段大小。可以类比keyword,区别是这个text会被分析一下,而keyword不会
- 综上,以上field保证索引的大小!
Solr 和 MySQL 的 FULLTEXT 索引都使用了倒排索引(Inverted Index)的结构来实现全文搜索。
倒排索引结构
倒排索引的核心由两部分组成:
- 词项字典 (Term Dictionary): 存储所有文档中出现的唯一词项,通常按照字母顺序排序,以便快速查找。
- 倒排列表 (Posting List): 对于词项字典中的每个词项,都有一个对应的倒排列表。这个列表记录了包含该词项的所有文档 ID,以及一些附加信息,例如词项在文档中出现的频率 (Term Frequency, TF)、词项在文档中出现的位置等等。 有些实现还会存储词项在文档中的偏移量,以便支持短语搜索。
为什么倒排索引能够支持全文搜索?
倒排索引之所以能够高效地支持全文搜索,主要是因为以下几个原因:
- 快速定位包含特定词项的文档: 通过词项字典,可以快速找到包含某个词项的倒排列表。倒排列表直接存储了包含该词项的文档 ID,避免了逐个文档扫描的开销。
- 易于进行布尔运算: 对于包含多个关键词的查询,可以通过对多个倒排列表进行交集、并集等布尔运算,快速得到满足查询条件的文档集合。例如,搜索 "brown fox",只需要获取 "brown" 和 "fox" 的倒排列表,然后取交集,即可找到同时包含这两个词项的文档 1。
- 支持更高级的搜索功能: 通过 在倒排列表中存储额外的信息,例如词频、位置等,可以支持更高级的搜索功能,例如短语搜索、基于相关度的排序等。
MySQL FULLTEXT 索引 和 Solr 的区别
虽然 MySQL 的 FULLTEXT 索引和 Solr 都使用了倒排索引,但它们之间还是存在一些区别:
- 功能丰富程度: Solr 作为一个专业的搜索引擎,提供了比 MySQL FULLTEXT 索引更丰富的功能,例如分词、拼写检查、高亮显示、faceted search 等。
- 可扩展性: Solr 具有更好的可扩展性,可以处理更大规模的数据和更高的查询负载。
- 更新机制: MySQL 的 FULLTEXT 索引通常与数据库事务绑定,更新索引会影响数据库性能。Solr 的索引更新机制更加灵活,可以进行增量更新,对数据库性能影响较小。