ElasticSearch是基于Lucene的搜索服务器,lucene承载了elasticSearch的核心算法和设计系想,所以要想彻底学透ElasticSearch需要从学习Lucene开始。
概念解析:
Lucene定义:基于Java的、高效的全文检索库。
基于java,因为它就是java的一套类包工具,并不是独立运行的产品,可以被拿来在上层开发各种属于自己的应用。
我们把重点放在什么是全文检索?
我们把数据分为两类:
结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据:指不定长或无固定格式的数据,如邮件,word 文档等。
非结构化数据中有些数据也被人拆分为半结构化数据:例如XML、HTML这类具有一定规则的非结构化数据。
先创建索引,再对索引进行搜索的过程就叫做全文索引。所以全文索引被拆分为两部分:索引的创建和索引的搜索。
(注意:这里需要强调一点的是,全文索引不仅适用于非结构化数据,也适用于结构化数据)
举例说明Google、百度等搜索引擎是通过爬虫不断的爬取internet上网站的信息(爬到的html文件可以理解为非结构化数据),然后对这些非结构化数据创建索引并将索引保存在公司的服务器磁盘中,这一过程是创建索引的过程。当我等用户通过搜索引擎输入关键字来查询想要的网站时,引擎根据关键字去索引里分析查找最符合条件的网页连接并做好排序推送给我们,这一过程是搜索索引。
索引究竟保存了什么?
非结构数据我们理解为一个文件,它是由很多字符串组成的,我们把从字符串到文件的映射的索引信息称为反向索引。
创建索引有哪些步骤?
文件一:Students should be allowed to go out with their friends, but notallowed to drink beer.
文件二:My friend Jerry went to school to see his students but found themdrunk which is not
allowed.
1, 词法分析、语言处理
我们拿到原文件后需要先一些处理,将文件拆分为一个个的单词、去除标点符号、去除一些无意义的单词(语气助词、the、a、阿等),这一步处理完后得到的产出是一个个词元(Token)
在我们的例子中,便得到以下词元(Token):
“Students”,“allowed”,“go”,“their”,“friends”,“allowed”,“drink”,“beer”,“My”,“friend”,
“Jerry”,“went”,“school”,“see”,“his”,“students”,“found”,“them”,“drunk”,“allowed”。
2, 语言处理组件修剪词元
因为语言特殊的魅力,Token还不能直接拿来做索引,我们还要做一次Token的转化和合并,例如英文中大小写、单复数形式、不同的时态,不同的Token其实都是在表达一个意思,所以我们要用语言处理组件做一次处理,处理后的产出叫词(Term)
在我们的例子中,经过语言处理,得到的词(Term)如下:
“student”,“allow”,“go”,“their”,“friend”,“allow”,“drink”,“beer”,“my”,“friend”,“jerry”,
“go”,“school”,“see”,“his”,“student”,“find”,“them”,“drink”,“allow”。
3, 生成索引
每个文件根据Term生成字典值,根据Term排序后合并,生成一个文档倒排列表
如图:
4, 存储索引
将以上索引存储到响应介质中,文件或者数据库文件格式。
查询索引做了哪些事情?
1,对查询内容进行词法分析、语言处理(同索引创建一样)
2,not、and、or等运算词的分析(参考oracle、mysql中的意义)
3, 搜索索引,根据前两步的内容去索引库中找到满足查询条件的索引列表
4, 计算权重对返回内容排序,这块比较难理解
需要了解2个概念:
Term Frequency(tf):即此 Term 在此文档中出现了多少次。tf 越大说明越重要。
Document Frequency (df):即有多少文档包含此Term。df 越大说明越不重要
df越小tf越大(某个词大家接触的本来就少而有一篇文章缺大肆用到这个词),越是我们想要搜索到的内容。
最后配一张图来加强下对创建索引和查询索引的理解: