Elasticsearch如何检索数据

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

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

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

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

为什么谈到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算法

(2)最新的基于概率论的BM25算法

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

早期的全文检索所有的数据都会被做成一个大的倒排索引,当新索引准备好之后,它会替代旧的大索引并且最近的变化数据可以被检索。

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

优点:

(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

原文发布于微信公众号 - 我是攻城师(woshigcs)

原文发表时间:2018-03-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构师学习

一个今日头条的面试题——LRU原理和Redis实现

很久前参加过今日头条的面试,遇到一个题,目前半部分是如何实现 LRU,后半部分是 Redis 中如何实现 LRU。

5332
来自专栏数据科学与人工智能

【Python环境】使用Python Pandas处理亿级数据

在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,Hado...

3095
来自专栏小詹同学

爬点重口味的 。

小弟最近在学校无聊的很哪,浏览网页突然看到一张图片,对面的女孩看过来(邪恶的一笑),让人想入非非啊,一看卧槽,左边这妹子彻底赢了,这(**)这么大,还这么漂亮,...

1512
来自专栏PPV课数据科学社区

【学习】在Python中利用Pandas库处理大数据的简单介绍

在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,...

4287
来自专栏小古哥的博客园

数据库设计入门

数据库是网络应用的基础,良好的表结构设计,对整个应用起着至关重要的作用。 数据库设计的步骤: 1.需求分析:数据是什么,有哪些属性,数据和属性的特点 2.逻...

4275
来自专栏非著名程序员

Android程序员必备精品资源

平时写程序中不断收集到的一些比较常用的东西,实用工具等,分享给大家。 实用工具集锦 Android Lifecycle https://github.com/x...

2087
来自专栏IT笔记

JAVA工作三年面试(二)

这里讲述下第二家公司的面试,这是一家大型互联网公司,简称W,一般像博主这样的传统行业去跳到这种公司简直是要跪舔的节奏,所以从一开始就带着一份敬仰之情去面试。由于...

4427
来自专栏数据和云

数据库时间出现'0000/00/00',难道我穿越了?

前几天有个朋友遇到一个问题,在做日期类型数据的运算的时候出现了‘0000-00-00’的结果,不得其解。你是否遇到过同样的问题呢?这样一个并不存在的时间点,难道...

3206
来自专栏Golang语言社区

Go语言实现控制台贪吃蛇

各位好 今天在关注GO相关文章的时候,看到一篇关于go语言实现贪吃蛇的文章,原文地址:http://outofmemory.cn ;尝试编译了...

4667
来自专栏大数据挖掘DT机器学习

使用Python Pandas处理亿级数据

原文:http://www.justinablog.com/archives/1357?utm_source=tuicool&utm_medium=refer...

4737

扫码关注云+社区

领取腾讯云代金券