Elasticsearch如何检索数据

咱们都知道Elasticsearch是一个全文检索引擎,那么它是如何实现快速的检索呢?html

传统的数据库给每一个字段都存储成一个单个值,对于全文检索而言,这样的存储是低效的。举个例子,我有一个大文本字段,存到数据库里面只能是一个值,若是想要检索这个大文本字段里面的任何一个词,数据库如何实现? 只能经过like模糊查询来实现,先不说性能低,这对于一个搜索引擎是远远不够的。算法

针对上面数据库的不足,因此才出现了Lucene这种全文检索框架而它的核心就在于采用了倒排索引(Inverted Index)的数据结构,不一样于数据库的行式存储,Lucene这里采用了列式存储的方式故而对单个字段能够支持多个值的存储,这就是倒排索引。数据库

Term  | Doc 1 | Doc 2 | Doc 3 | ...
------------------------------------
brown |   X   |       |  X    | ...
fox   |   X   |   X   |  X    | ...
quick |   X   |   X   |       | ...
the   |   X   |       |  X    | ...

如上图所示,倒排索引的一个字段由多个Term组成,这些Term是一个有序的列表,而且是惟一不重复的。对于每个Term又会映射上全部包含该Term的Document Id列表。json

为何谈到Lucene,由于Lucene自己只是一个全文检索工具包,它不具有企业级的一些特性,如分布式,副本,扩展等而Elasticsearch和Solr都是基于Lucene开发和扩展的企业级框架,因此了解Lucene对学习Elasticsearch和Solr会有很大帮助。缓存

在Elasticsearch中每条数据都是一个json,实际上json中每个字段都有它本身的倒排索引结构。数据结构

固然倒排索引中的每一个Term保存的信息还有不少,好比这个Term在多少个Doucuments里面出现过的次数,在特定的Doucument里面出现的次数,每一个Document的length,全部Document的平均length,这些信息是用来计算搜索的相关性(Relevance),咱们都知道使用google和百度搜索结果后,数据会有个前后排名,排名靠前的基本都是最相关的数据,那么那些因素决定了数据的排名? 这里面其实就是上面所说的相关性来决定,关于相关性的计算方式也是Lucene里面的核心功能,目前Lucene里面主要有两种Rank算法:框架

(1)经典的基于VSM向量空间的TF/IDF算法elasticsearch

(2)最新的基于几率论的BM25算法分布式

刚兴趣的朋友能够去维基百科学习一下,这里再也不展开了。ide

早期的全文检索全部的数据都会被作成一个大的倒排索引,当新索引准备好以后,它会替代旧的大索引而且最近的变化数据能够被检索。

这个大的倒排索引有一个最大的特色就是不可变性,只要索引被写入磁盘后,就是不可变的:

优势:

(1)因为不可变性,因此不须要锁,也就是不存多个线程同时去修改数据。

(2)能够直接把索引加载到FileSystem Cache停留在cache中,由于它不会被修改而且FileSystem Cache有足够大的空间,这样以来直接在内存中查询代替在磁盘上,对搜索性能大大提高。

(3)其余的缓存如filter cache在整个index的生命周期内都是有效的,他们不会被重建,由于索引是不可变的。

(4)不可变的大索引能够获得更高的压缩比,这样以来可以节省io和占用的内存资源

缺点:

倒排索引的优势也是它的缺点,由于它不可变,因此为了使你新增的数据可以正常的搜索到,你须要重建整个索引,这严重限制了单个index存储的数量以及它的更新频率。

因此在Elasticsearch中采用了动态更新多个索引方式来解决这个问题,这个会在下篇的文章中介绍。

参考连接:

https://www.elastic.co/guide/en/elasticsearch/guide/master/inverted-index.html

https://www.elastic.co/guide/en/elasticsearch/guide/master/relevance-intro.html

https://www.elastic.co/guide/en/elasticsearch/guide/master/making-text-searchable.html

相关文章
相关标签/搜索