用了Elasticsearch后,查询起飞了

最近接触的几个项目都使用到了Elasticsearch(以下简称ES)来存储数据和对数据进行搜索分析 , 就对ES进行了一些学习 。 本文整理自我自己的一次技术分享 。
用了Elasticsearch后,查询起飞了
文章图片
图片来自包图网
本文不会关注ES里面的分布式技术、相关API的使用 , 而是专注分享下“ES如何快速检索”这个主题上面 。 这个也是我在学习之前对ES最感兴趣的部分 。
本文大致包括以下内容:
关于搜索:
传统关系型数据库和ES的差别搜索引擎原理细究倒排索引:
倒排索引具体是个什么样子的(postinglist→termdic→termindex)关于postingslist的一些巧技(FOR、RoaringBitmaps)如何快速做联合查询?关于搜索
先设想一个关于搜索的场景 , 假设我们要搜索一首诗句内容中带“前”字的古诗 。
用了Elasticsearch后,查询起飞了
文章图片
用传统关系型数据库和ES实现会有什么差别?如果用像MySQL这样的RDBMS来存储古诗的话 , 我们应该会去使用这样的SQL去查询:
selectnamefrompoemswherecontentlike''%前%'';这种我们称为顺序扫描法 , 需要遍历所有的记录进行匹配 。 不但效率低 , 而且不符合我们搜索时的期望 。
比如我们在搜索“ABCD''这样的关键词时 , 通常还希望看到''A'' , ''AB'' , ''CD'' , “ABC”的搜索结果 。 于是乎就有了专业的搜索引擎 , 比如我们今天的主角ES 。
搜索引擎原理
用了Elasticsearch后,查询起飞了
文章图片
搜索引擎的搜索原理简单概括的话可以分为这么几步:
内容爬取 , 停顿词过滤 , 比如一些无用的像''的'' , “了”之类的语气词/连接词内容分词 , 提取关键词根据关键词建立倒排索引用户输入关键词进行搜索这里我们就引出了一个概念 , 也是我们今天的要剖析的重点倒排索引 。 也是ES的核心知识点 。
如果你了解ES应该知道 , ES可以说是对Lucene的一个封装 , 里面关于倒排索引的实现就是通过lucene这个jar包提供的API实现的 , 所以下面讲的关于倒排索引的内容实际上都是lucene里面的内容 。
倒排索引
首先我们还不能忘了我们之前提的搜索需求 , 先看下建立倒排索引之后 , 我们上述的查询需求会变成什么样子 。
用了Elasticsearch后,查询起飞了
文章图片
这样我们一输入“前” , 借助倒排索引就可以直接定位到符合查询条件的古诗 。
当然这只是一个很大白话的形式来描述倒排索引的简要工作原理 。 在ES中 , 这个倒排索引是具体是个什么样的 , 怎么存储的等等 , 这些才是倒排索引的精华内容 。
①几个概念
在进入下文之前 , 先描述几个前置概念 。
term:关键词这个东西是我自己的讲法 , 在ES中 , 关键词被称为term 。
postingslist:还是用上面的例子 , {静夜思 , 望庐山瀑布}是''前''这个term所对应列表 。 在ES中 , 这些被描述为所有包含特定term文档的id的集合 。
由于整型数字integer可以被高效压缩的特质 , integer是最适合放在postingslist作为文档的唯一标识的 , ES会对这些存入的文档进行处理 , 转化成一个唯一的整型id 。
再说下这个id的范围 , 在存储数据的时候 , 在每一个shard里面 , ES会将数据存入不同的segment , 这是一个比shard更小的分片单位 , 这些segment会定期合并 。
在每一个segment里面都会保存最多2^31个文档 , 每个文档被分配一个唯一的id , 从0到(2^31)-1 。
用了Elasticsearch后,查询起飞了