1.1:什么是全文检索
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之为索引。
例如:字典,字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找到一个字只能顺序扫描。
然而字的某些信息可以提取出来进行结构化处理,比如读音,就比较结构化,分声母和韵母,分别只有集中可以一一列举,于是将读音拿出来按照一定顺序排列,每一项读音都指向此字的详细解释的页数。
我们搜索时按照结构化的拼音搜索到读音,然后按其指向的页数,便可找到我们的非结构化数据--也即对字的解释。
这种先建立索引,再对索引进行搜索的过程就叫做全文检索。
虽然创建索引的过程是非常耗时的,但是索引一旦创建就可以多次使用,全文检索的主要处理的是查询,所以耗时间创建索引也是值得的。
比如:使用全文检索,搜索“生化危机”
有4条数据将每条数据进行词条拆分。
如“生化危机电影”拆成:生化,危机,电影关键词(拆分结果与策略算法有关)每个关键词将对应包含此关键词的数据ID搜索的时候,直接匹配这些关键词,就能拿到包含关键词的数据这个过程就叫做全文检索。而词条拆分和词条对应的ID这个就是倒排索引的基本原理。
1.2:对比数据库的缺陷
mysql如果没有索引的情况下,共有100万条,按照之前的思路,其实就要扫描100万次,而且每次扫描,都需要匹配那个文本所有的字符,确认是否包含搜索的关键词,而且还不能将搜索词拆解开来进行检索。
1.3:利用倒排索引
进行搜索的话,假设100万条数据,拆分出来的词语,假设有1000万个词语,那么在倒排索引中,就有1000万行,我们可能并不需要搜索1000万次,很可能说,在搜索到第一次的时候,我们就可以找到这个搜索词对应的数据,也可能是第100次,或者第1000次。
1.4:全文检索使用场景
①、维基百科,类似百度百科,牙膏,牙膏的维基百科,全文检索,高亮,搜索推荐。
②、The Guardian(国外的新闻网站),类似搜狐新闻,用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析,给到每篇新闻文章的作者,让他知道他的文章的公众反馈(好,坏,热门,垃圾,鄙视,崇拜)。
③、Stack Overflow:国外的程序异常谈论论坛。
④、GitHub:开源代码管理,搜索上千亿行代码
⑤、电商网站:检索商品。
⑥、日志数据分析:ES进行复杂的数据分析
⑦、商品价格监控网站:用户设定某商品的价格阈值,当低于阈值的时候,发送通知消息给用户。
⑧、BI系统,商业智能,比如说有个大型商场集团,BI,分析一下某某区域最近3年的用户消费金额的趋势以及用户群体的组成构成,产出相关的数张报表。ES执行数据分析和挖掘,Kibana进行数据可视化。
- 5:ES简介
es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储,检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
es也使用java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
es是面向文档的,这意味着它可以存储整个对象或者文档,然而它不仅仅是存储,还会索引index每个文档的内容使之可以被搜索。
在es中,可以对文档(而非成行成列的数据)进行索引,搜索,排序,过滤。
es对比传统关系型数据库如下:
es提供多种语言的支持,其中java的客户端为Java REST Client。
而它又分为两种:高级和低级的。高级包含更多的功能,如果把高级比作MyBatis的话,那么低级就相当于JDBC,是基于Netty和Server通讯相关。
高级的Client类似MyBatis是对Low Level的封装
1.6:ES基本概念
①、索引库
ES将它的数据存储在一个或者多个索引index中。用SQL领域的术语来类比,索引就像是数据库,可以向索引写入文档或者从索引中读取文档。并通过es内部使用Lucene将数据写入索引或者从索引中检索数据。
es使用倒排索引来做快速的全文搜索,这点与数据库不同,一般数据库的索引,使用B+Tree来实现。索引库就是存储索引的保存在磁盘上的一系列的文件。里面存储了建立好的索引信息以及文档对象,一个索引库相当于数据库中的一张表。
②、document对象
获取原始内容的目的是为了索引,在索引前需要将原始内容创建成文档document,文档中包含了一个一个的域field,域中存储内容。每个文档都有唯一的编号,就是文档id。document对象相当于表中的一行记录。文档是es中的主要实体。对所有使用es的案例来说,它们最终都可以归纳为对文档的搜索。文档由字段构成
③、field对象
如果把document看做成是数据库中一条记录的话,field相当于是记录中的字段,field是索引库中存储数据的最小单位,field的数据类型大致可以分为数值类型和文本类型,一般需要查询的字段都是文本类型的。field还有如下属性:
A:是否分词:是否对域中的内容进行分词处理,前提是我们要对域的内容进行查询。
B:是否索引:将Field分析后的词或整个Field值进行索引, 只有索引方可以搜索到,比如:商品名称,商品简介分析后进行索引,订单号,身份证号并不用分词但是也要索引,这些将来都要作为查询条件。
C:是否存储,将Field值存储在文档中,存储在文档中的Field才可以从Document中获取,比如:商品名称,订单号,凡是将来要从Document中获取的Field都要存储。
④、term对象
从文档对象中拆分出来的每个单词叫做一个term,不同的域中拆分出来的相同的单词是不同的term。term中包含两部分一部分是文档的域名,另一部分是单词的内容。term是创建索引的关键词对象。
⑤、类型(type)
每个文档都有与之对应的类型type定义。这允许用户在一个索引中存储多种文档类型,并为不同文档提供类型提供不同的映射。
type的版本迭代:
A:5.X及以前的版本一个index有一个或者多个type。
B:6.X版本一个index只有一个type。
C:7.X版本移除了type,type相关的所有内容全部变成了Deprecated,为了兼容升级和过渡,所有的7.X版本es数据写入后type字段都默认被设置为_doc。
D:8.X版本完全废弃type。
⑥、映射(mapping)
mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型,默认值,分析器,是否被索引等等。这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按照最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。
⑦、分片(shard)
代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上,构成分布式搜索,分片的数量只能在索引创建前指定,并且索引创建后不能更改。
5.X版本以及以后的版本不能通过配置文件定义分片,ES默认5:1 5个主分片,每个分片,1个副本分片。
官方文档的解释如下:
当索引一个文档的时候,文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢?首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。实际上,这个过程是根据下面这个公式决定的:shard = hash(routing) % number_of_primary_shards
routing 是一个可变值,默认是文档的_id,也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到 余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了
⑧、副本(replicas)
代表索引副本,es可以设置多个索引的副本,副本的作用:
A:提高系统的容错性,当某个节点某个分片损坏或者丢失可以从副本中恢复。
B:是提高es的查询效率,es会自动对搜索请求进行负载均衡。
⑨、集群(cluster)
代表一个集群,集群中有多个节点node,其中一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的,es的一个概念就是去中心化,字面上列就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。