之前天真的以为,会了es的全部API,就是搜索引擎工程师。
可是会了这些api,只能搬砖。
想要更加有深度的学习搜索推荐,于是向下进行延伸知识点。想去真正的了解搜索引擎,想要淌一下水有多深!
什么是搜索? —— 从形式上来说说什么是搜索这个框叫做搜索。这是浏览器类型的搜索。
这个也叫搜索,这是电商类的搜索。
不管是哪种类型的搜索,形式都一样。在框中输入你关心的内容,然后点搜索,返回和你关心相关的内容。
搜索的几个核心需求
- 搜索速度。
- 搜索内容相关度高。用白话说就是:搜的是我想要的。
看起来需求很少,很简单。可就是这两个需求,一个稍微大点的公司,可能得几十个人来维护这个小小的搜索框。
搜索速度,关系到了数据结构,关系到了搜索集群规模。
搜索内容相关度高。这个是最难的,涉及到了非常多的算法。涉及到了自然语言处理、涉及到了且此、涉及到了相关性计算排序 等等
先说一下elasticsearch 和 lucene的关系提到搜索,应该多数人想到的是elasticsearch。利用elasticsearch来搭建搜索集群。elasticsearch是可以满足我们的搜索需求。但是实际上对数据的操作,核心处理,并不是它。而是 Lucene,另外一个开源的技术,由java语言编写的文本搜索函数库。而es的核心功能就是基于lucene做的。
这里我暂时把lucene理解成 linux内核,而elasticsearch相当于是 centos或者 Ubuntu。其实不难理解,说起linux,大家很少提内核。更多的是想到centos这样的可直接使用的系统。同样的道理,提到搜索引擎,大家想到的是elasticsearch。
即使没写核心的搜索算法,但是elasticsearch依然是非常出色的产品。在lucene这个搜索函数库上做了非常多的工作,以至于光芒掩盖了lucene。给我们提供了分布式管理,使它作为搜索引擎,更加具备扩展性,这点我们可以描述为集群管理。为我们提供可视化展示界面(kibana),为我们提供了一整套数据处理方案。
如果你能把elasticsearch原理搞得很清楚的话,今后在公司搞分布式应用,应该是手到擒来的事情。es给我们提供了非常好的分布式架构经验。我们可以学习一下es是如何解决分布式问题的。
好好使用elasticsearch满足上边提到的搜索框的需求,好好学学 elasticsearch的API差不多够了。但是想要做到更加极致,在现有的基础上,还想有更加明显的提升。有两步,第一步是合理使用elasticsearch,合理规划集群,合理分配分片,合理配置机器资源。第二步应该去关注底层的存储原理了。还是建议有深度的学习一下 lucene这个核心搜索函数库。
一次搜索过程一次搜索过程,实际上有以下几个过程
- 搜索内容纠错以及搜索提示。搜索提示是一种系统更加友好的体现。而纠错则是系统更加智能的体现。
- 分词。前一个步骤保证了用户的输入内容没有问题。在没有问题的基础上,搜索出来的内容才有可能是用户关心的。而分词,则是对用户输入的内容进行分割,然后用户在搜索引擎中检索,找到与之相关度最高的内容。仅仅是一个分词,就有非常多的问题要考虑。比如语言问题,英语和中文的分词就不一样。英文通过空格分割就可以了,而中文却不能简单的根据标点符号分割。这又涉及到了自然语言处理。分词不准确,就像目标歪了,很难搜索到内容。想要把分词做的足够好,就要研究分词算法。特别是在中文情况下,经过语义分析,能提高分词的准确性。这又涉及到了自然语言处理。 关于分词,我们要考虑的是如何选择合适的分词器,来应对我们的场景,真的去研究算法,自研分词器,会有很大的困难。
- 关键词匹配。或者说是关键词检索。从存储引擎中搜索到和用户输入的关键词相关的文章。这一步就是要匹配大到与之相关的内容。这就涉及到了如何存储内容,例如使用倒排索引。
- 搜索排序。通常情况下,根据某些条件搜索。得到的结果又很多,真正能展示的内容却有限。这时候,如何从结果中拿到最好的结果,相关度最高的结果,就要对搜索结果进行排序。这个向下研究的话,有搜索模型,例如:布尔检索模型、向量空间检索模型、概率论检索模型等等。选择合适的模型来解决实际的问题。才能有更好的效果。
分词器是专门处理分词的组件,分词器由以下三部分组成:
- Character Filters:针对原始文本处理,比如去除 html 标签
- Tokenizer:按照规则切分为单词,比如按照空格切分
- Token Filters:将切分的单词进行加工,比如大写转小写,删除 stopwords,增加同义语
标准分词器:就是一个字一个字的。输入 中国的城市 , 然后每各字当做一个词。 很鸡肋
空格分词器:针对输入的内容,就按照空格给你分割。这很适用于英文。
简单分词器:根据符号来分割。粒度太大了。很容易出现搜不出来结果的情况。
二分分词器:这个也是很笨的分词方法,没有算法在里边。会造成很多的冗余。例如:输入 中国的城市, 分词结果就是: 中国 | 国的| 的城| 城市 。
停用分词器
中文智能分词器:这个分词结果基本上是我们想要的了。
ES支持的分词器es分词器 参考文章
IK分词器加上自定义分词词库,就比较不错的解决方案。另外可以看看阿里达摩院的基于 NLP的分词器叫做 AliNLP
周末读了一本书《从lucene到Elasticsearch全文检索实战》这本书,就是入门级别的,如果英文水平不错的话,读官方文档更好一点。这就像一本一个翻译过来的es文档。没太大的作用。就是告诉你有哪些api,背后原理是什么,是没有的。如果想拿这本书拔高的话,这里劝退吧。
在我看来最优价值的是第一章,对信息检索模型的认知。告诉我们相关的搜索算法。
普通就像一道光,晴天下,不会引起任何人的注意。可是拿到黎明前的至黑至暗时刻,却又是那样的神圣。抓住这道普通的光,在至黑至暗的生活中凿开一个洞!
如果你就是觉得做的事情是平凡的,如果更加有深度的去研究一下呢?是不是就不平凡了?