倒排索引
倒排索引是 ES 中非常重要的索引结构,是从 文档词项到文档ID 的一个映射过程。
“ 正排索引 ”
我们在关系型数据库中见到的索引,就是“正排索引”。
关系型数据库中的索引如下,假设我们有一张博客表,内容如下:
id | 作者 | 标题 | 内容 |
---|---|---|---|
1 | sakura1 | 倒排索引 | 1234567890 |
2 | sakura2 | 正排索引 | adcdefghi |
我们可以针对这个表建立索引(正排索引):
比如根据id,根据作者,根据标题去建立索引。
这样我们搜索文章时,无论根据id,作者,标题都可以快速搜索到。
但是当我们按照文章内容去搜索时,先不考虑内容字段是否适合建立索引,即使给内容字段建立索引,我们在查询时,也不可能将全部内容作为搜索条件去搜索。
如果我们按照文章关键字去搜索,比如哪篇文章内容包含abcd,那么只能去做字符匹配了,这样效率也非常低。
1 | select * from blog where content like '%abcd%'; |
为了提高查询效率,就要考虑使用到倒排索引。
倒排索引
倒排索引就是以内容的关键字建立索引,通过索引找到文档id,再进而找到整个文档。
比如对于上面博客表,有4条数据,如下:
id | author | title | content |
---|---|---|---|
1 | javazwt | java | java is very good,and I like elasticsearch |
2 | sakura | elasticsearch | elasticsearch is very very good |
3 | sakuratears | php | I like php and elasticsearch |
4 | sakura | 12345 | php is very good |
则我们根据内容content关键字建立倒排索引,结果如下:
索引 | ids | id=1 | id=2 | id=3 | id4 |
---|---|---|---|---|---|
java | 1 | * | |||
is | 1,2,4 | * | * | * | |
very | 1,2,4 | * | * | * | |
good | 1,2,4 | * | * | * | |
and | 1,3 | * | * | ||
I | 1,3 | * | * | ||
like | 1,3 | * | * | ||
elasticsearch | 1,2,3 | * | * | * | |
php | 3,4 | * | * |
比如此时我们想搜索elasticsearch相关文章内容,则根据倒排索引可以快速定位到文档1,2,3,进而快速拿到整个文档信息。
我们之前提到过停用词,比如我们建立文档时指定了停用词,比如is,那么建立倒排索引时 is 便不会被索引。
之前说过的分词器,其功能就是将我们的content正确分词。
一般来说,倒排索引分为两个部分:
- 单词词典:记录所有文档词项,以及词项到倒排列表的关联关系。
- 倒排列表:记录单词与对应的关系,由一系列倒排索引项组成,倒排索引项:文档id、词频(TF)(词项在文档中出现的次数,比如上例中的very,在文章2中出现了两次,可以认为文档2搜索相关度更高一些)、位置(词项在文档中分词的位置)、偏移(记录词项开始和结束的位置)。我们上例仅仅使用了文档id倒排索引项。
当我们去索引一个文档时,就会建立倒排索引,搜索时,直接根据倒排索引进行搜索。