前言: 到底什么是搜索引擎?
对于我们传统的应用来说, 常见的搜索无非是用户通过前端发起请求给后端, 后端去DataBase中比如MySQL, Oracle 中完成查询,并返回,这个查询可能是精确匹配,模糊匹配等等,但是这样的搜索功能可以被称之为搜索引擎吗? 或者说合格的搜索引擎,显然是不能的,因为在一些特殊情况下,我们单纯基于DataBase的搜索召回过于局限了,举个例子,比如现在数据库中有一些关于国家的信息,比如中华人民共和国,美国,法国等等,现在用户就是输入了一个中国,那么传统的关系型数据如何匹配到中华人民共和国呢,无论是精确匹配还是模糊匹配都不可能搜索到结果,除非我们专门做了一层映射关系,让系统知道它应该查找哪条数据,当然这显然也是不合理的,因为我们的数据量可能是非常庞大的,这种办法是根本不可靠,还有常见的排序问题,关系型数据库中的orderBy操作也有一定的局限性,过于死板,因此,搜索引擎的介入就是为了以一种更加优雅的方式来解决我们常见关系型数据库当中查询召回的一些痛点,常见的搜索引擎有ElasticSearch, Solr, 本文章主要以ElasticSearch来展开
第一章
ElasticSearch是什么
- Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间数据等。它能够提供近乎实时的搜索和分析功能。Elasticsearch 常被用于解决各种搜索和数据分析问题,例如日志分析、全文检索、以及需要高性能和高扩展性的复杂查询场景。
- Elasticsearch 是基于 Lucene 开发的,但它的目标是更容易地实现分布式搜索和索引,提供一个更为高级的结构化搜索接口以及一个可扩展的系统来处理大量数据。它还提供了 RESTful 接口,使得开发者可以方便地通过 HTTP 协议用 JSON 数据格式进行交互。
ElasticSearch的一些名词定义
ElasticSearch中的索引 = 数据库
ElasticSearch中的类型 = 表
ElasticSearch中的文档 = 数据库表中的行数据
ElasticSearch中一些关键词概念与传统关系型数据库的对应关系
| Relational Database | ElasticSearch |
|---|---|
| DataBase | Index |
| Table | Type |
| Row | Document |
| Column | Field |
| Schema | Mapping |
| Index | Everything Index |
| SQL | Query DSL |
| SELECT * FROM TABLE | GET http://… |
| UPDATE TABLE SET | PUT http:// |
ElasticSearch的一些特点
- 分布式:ElasticSearch 可以部署在一个或多个服务器上,形成一个集群,能够处理大量的数据和流量
- 实时性:数据可以在短时间内被索引并供搜索使用
- 可扩展性:随着数据量的增长,可以通过添加更多的节点来扩展 ElasticSearch 集群
- 高可用性:通过复制数据到多个节点上,即使某个节点失败也能保证服务的可用性
- 丰富的 API:提供多种语言的客户端库,以及易于使用的 RESTful API, 由于支持 RESTful 风格的方式进行访问,也就是基于HTTP的方式, 让它可以几乎可以跟任何代码开发的应用进行交互
ElasticSearch的基本原理是什么? 什么是倒排索引?
- Elasticsearch 被设计为可分布式的,这意味着它可以跨多个节点运行,每个节点都是集群的一部分。集群中的每个节点都可以包含一个或多个索引,索引可以被复制和分割成多个分片来提高可用性和性能
- Elasticsearch 使用倒排索引来加速搜索。传统的正向索引是从文档到词的映射,而倒排索引则是从词到文档的映射。这意味着对于给定的查询词,Elasticsearch 可以迅速找到包含该词的所有文档。这个具体意思是什么后面我会画图来解释。
- Elasticsearch 中的数据是以 JSON 格式存储的文档。每个文档都属于一个特定的索引,索引可以包含多种类型的文档。不过,在 Elasticsearch 6.x 及更高版本中,类型的概念已被弃用,现在索引中只能有一种类型,默认为"_doc"。
- 当执行搜索请求时,请求会发送到主节点,主节点将请求广播到相关的分片所在的节点上。每个节点会处理请求然后返回结果给主节点,主节点汇总这些结果后返回给客户端。这里也看到了,ElasticSearch的多节点主从架构和类似Redis的多节点主从架构是有一些区别,ElasticSearch的主节点是不存储数据的, 只负责集群分片的维护, 告诉你数据应该去哪个分片上找, 同时也负责索引的创建/删除/分片分配/节点状态管理等操作, 这和Redis集群的主节点是不一样的, Redis主节点也会写入数据, 还有同步给从节点, 这是有区别的
- 为了提高容错性和可用性,Elasticsearch 允许创建索引的副本。如果一个节点失败了,另一个节点上的副本可以接管请求。此外,大的索引会被分成多个分片来分散负载和提高检索速度。
- 所有的功能都可以通过 HTTP 请求与响应来访问。这意味着你可以使用任何语言来与 Elasticsearch 进行交互。
- Elasticsearch 支持实时插入、更新和删除文档,并且可以在数据写入的同时进行查询。
- Elasticsearch 设计为易于水平扩展,即可以通过添加更多的节点来增加系统的存储能力和处理能力。
- Elasticsearch 经常与 Kibana 结合使用,后者是一个用于可视化 Elasticsearch 数据的强大工具。Kibana也是ElasticSearch最常见的一个搭配组件中的一个, 也就是ELK中的K,L是什么后面再说
倒排索引的解析
在了解倒排索引的基础上,我们先要了解一下正排索引
正排索引:
- 假设我们现在有若干篇文档,每篇文档内容都不一样,对应也分出了若干个词, 现在我们输入了一个“中国”,那么对于正排索引,它会怎么搜索呢? 它会从头到尾依次遍历文档,直到找出哪篇文档当中出现了我要搜索的词, 这里的问题就在于,乐观的情况下,比如中国这个词正好就只出现在了第一篇文档当中,一次就查到了,不理想的情况,我可能要遍历完所有的文档才能找到结果,比如下图可能doc1 doc2 doc3都没找到我要的内容,那就比较糟糕了,只能继续往下遍历了

倒排索引:
1.倒排索引的设计思想是说,既然正排搜索是文档到词的映射,那么我可以建立一个词到文档的映射,也就是说在建立索引的时候,中国这个词就相当于一个key,与之对应的就是,哪些文档中出现过中国,那么这个时候显而易见,我可以直接根据词把对应的文档找出来,比如下图,找到了word1和word2关联的文档有中国这个词,不需要在再逐个去遍历文档了,这当中的效率的效率提升是非常高的
2.
ElasticSearch的分词概念(倒排索引的构建也是依赖分词)
- 在 Elasticsearch 中,分词是文本处理的重要组成部分,尤其是在建立索引和搜索过程中。分词是指将文档中的文本分解成更小单元——通常是单词或短语,这些单元被称为“tokens”。分词器是负责将输入文本转换为 tokens 的组件,比如ik分词器(专门为中文文本处理设计的一种分词器), 举个例子,现在我们有一个字符串"小明是我的同学", 那么对应分词器可能被分为 小明,是,我,我的,同学这几个词,当然具体的分词粒度是可以设置的,比如最大粒度的切分,最小粒度的切分, 就是说尽最大可能性拆分,比如直接拆成一个字一个字的,或者尽可能的满足语义的拆分
- 分词并没有最好的方式,只有更加适合业务的方式,比如设置ik分词器的分词方式为ik_max_word,虽然搜索召回的可能性比较高,任意一个词命中了都会返回,但是召回的数据不一定是用户真正想要的,如果设置ik分词器的分词方式为ik_smart,那么虽然拆分的词,精确度更好了,但是召回的可能性会下降,不是很贴近语义的输入就会导致无法命中分词
- 那有没有一种好的方式我既要分词最大化,并且我还要保证搜索时精确度呢,当然是有的,最简单的做法就是我们将ik_max_word和ik_smart结合使用,什么意思呢? 就是说我们在设置分词构建索引的时候设置为ik_max_word, 但是在搜索解析时我们设置为ik_smart,这样可以利用 ik_max_word 的高召回特性,同时利用 ik_smart 的高精确度特性。
ElasticSearch中TF-IDF打分的策略
- Term Frequency (TF):词频,表示一个词在文档中出现的频率。TF 越高,说明该词在文档中的重要性越高。
- Inverse Document Frequency (IDF):逆文档频率,表示一个词在整个文档集合中的重要性。IDF 越高,说明该词越罕见,因此越重要。
- TF很好理解, 那么IDF是什么意思呢? 总的来说,可以理解为稀有度,也就是说虽然这个词,在整个文档当中只出现了一次,但是它的IDF值就会很高,它很稀有
- 一个词如

439

被折叠的 条评论
为什么被折叠?



