读完本文章,你将会明白:
1.为什么需要搜索引擎。
2.搜索引擎技术是什么、用来解决什么问题(场景)的。
3.搜索引擎是怎么解决问题的,搜索引擎的核心概念、工作流程、原理。
4.市面上常用的搜索引擎框架
一、为什么需要搜索引擎?
问:查询商品,在数据库中如何做查询?
按类别、标题或关键字等查询或者模糊查询。
核心SQL: = 、 in(…) 、 like
再问:当数据量变大时,查询变慢了,该如何优化?
1.建索引
2.分表
追问:在数据库中如何判断一个列是否可以建索引?
基本原则:
- 表经常被访问,且数据量很大,而每次查询的数据只占很小很小一部分
- 列的数据值分布范围广泛
- 列被经常用在查询条件
- 文本列需特殊考虑:需要使用全文索引。
首先,明确几种数据的分类。 - 结构化数据: 用表、字段表示的数据
- 半结构化数据: xml html等标签语言
- 非结构化数据: 文本、文档、图片、音频、视频等
小结
数据库适合结构化数据的精确查询,而不适合半结构化、非结构化数据的模糊查询及灵活搜索(特别是数据量大时),无法提供想要的实时性。所以需要专门的搜索引擎提供服务。
二、搜索引擎的核心概念
和数据库一样,搜索引擎要想加速查询速度,也需要使用索引。那么通常使用的索引是什么形式呢。
1.反向索引(Inverted index)和分词器
反向索引建立从词项 (term) 到文档(document) 的映射关系。
词项 | 文档 |
---|---|
term1 | doc1,doc3 |
term2 | doc2,doc3 |
搜索引擎中索引的key通常是有语义的词汇,量不会很大,所以通过索引查找会很快。那么如何建立这样一个索引?
示例:
标题:张三说的确实在理
1.一句话怎么分成多个词?
计算机不像人能够智能判断,需要依据设定好的规则。如果是英文文章,可以简单地用空格分割。中文语境更加复杂,比较难分。但不分词就无法建立反向索引。就必须写一套专门的程序来做这个事情:分词器。
2.分词器与自然语言的关系是怎样?
每门语言有对应的分词器。
3.如果要开发一个中文分词器,该怎么实现对一句话进行分词?
思考我们自己是如何做的:从头开始一个一个字读,通过前后字的组合,分出:张三、说的、确实、在理。
问:我们是怎么确定张三、说的、确实是词?
因为我们的大脑里有个词的字典,通过与字典匹配来确定。
问:为什么我们不会分出:张三、说的、的确、确实、实在、在理?
因为我们的大脑可以进行歧义分析。
问:你、我、他、的、地、了、标点符号等需要为其创建索引吗?
这些词称为:停用词。可以在分词器中指定停用词。
问: 当出现了新词了该怎么办?
部分分词器支持为其词典添加新词。
中文分词器原理:有个词的字典,对语句前后字进行组合,去除停用词,与字典匹配,并进行歧义分析,最后得到分解后的词项(term)并建立索引。
问:建立好索引后如何进行查询呢?
示例
输入“说的在理”
- 对输入做分词,得到“说”、“在理”,“的”通常作为停用词直接就去掉了。
- 在索引中查找包含“说”和“在理”的文档。根据定义的操作符决定是 与、或 还是其他关系。
- 对得到的文档结果排序,通常定义相关度最高的排在最前面。
问:如何判断相关度高低?只用包含词项这一条规则够吗?这就引出另一个核心组件:相关性评估模型。
2.相关性评估模型
简单地评估模型可以用词项的出现次数,所在的字段权重等,但是不具有统计意义,有时不够准确。
复杂的相关性计算模型有:
tf-idf 模型、向量空间模型、贝叶斯概率模型,如: BM25(Solr默认使用的模型)
搜索引擎通常会提供一种、或多种实现供选择使用,大佬可以根据特殊场景自己去做改造,但大部分场景下这些算法的具体逻辑对程序员是透明的,也不需要去做改动,Solr中还提供了很多可以影响评分的参数,足以满足常规需求。
小结
- 搜索引擎由数据源、分词器、反向索引、相关性计算模型等核心部件组成。
- 搜索引擎的工作流程:从数据源加载数据,分词,建立反向索引。搜索时,对输入进行分词,查找索引,计算相关性,排序,输出