美文网首页
Elasticsearch 倒排索引

Elasticsearch 倒排索引

作者: SheHuan | 来源:发表于2020-12-08 21:14 被阅读0次

    之前我们已经了解过,Elasticsearch 是一个基于 Lucene 实现的分布式全文检索引擎,其实 Elasticsearch 倒排索引就是 Lucene 的倒排索引。数据检索是 ES 的一项核心功能,它的底层实现也是离不开倒排索引的,通过倒排索引技术可以提高数据的检索效率,理解倒排索引的原理很重要。

    那什么是倒排索引,我们该如何理解它呢?

    我们能进行数据检索的前提条件是,已经创建好了索引库,并给里边添加了文档数据。所以我们可以按照创建索引库添加文档数据检索这个顺序来认识倒排索引。

    1、

    首先是创建索引库,我们之前已经安装好了 IK 分词器,这里我们创建一个test索引,它只有一个content字段,添加文档时字段的分词模式是ik_max_word,检索时关键字的分词模式是ik_smart

    PUT test
    {
      "mappings": {
        "properties": {
          "content":{
            "type": "text",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_smart"
          }
        }
      }
    }
    

    字段的分词模式会影响最终生成的倒排索引。不了解分词器的可以参考Elasticsearch 中文分词器插件

    2、

    创建好了索引,我们来添加一条文档数据:

    POST test/_doc/1
    {
      "content": "长安十二时辰"
    }
    

    添加文档数据时,ES 会根据字段的分词模式将字段的值拆分成多个词条(Term)(或者称作词项),创建索引库时我们指定了content字段分词模式为ik_max_word,则会生成如下的词条:

    词条
    长安
    十二时
    十二
    时辰

    接下来就是建立倒排索引了,在这之前我们先了解两个概念词条字典(Term Dictionary)、倒排列表(Posting List):

    • 词条字典,就是词条的集合,不会出现重复词条,同时其中的词条会被排序。
    • 倒排列表,由多个倒排列表项组成,倒排列表项记录了词条对应的文档id、词条在对应文档字段的出现频率、出现的位置以及偏移量等信息。

    ES 的倒排索引就是由词条字典倒排列表两部分组成的。如下就是一个简易版的倒排索引,倒排列表项只有词条对应的文档 id:

    词条 倒排列表项
    长安 [1]
    十二时 [1]
    十二 [1]
    时辰 [1]

    一个词条对应一个倒排索引项。ES 会给每个字段都建立一个倒排索引。

    我们再添加一条文档数据:

    POST test/_doc/2
    {
      "content": "十二生肖"
    }
    

    根据上边的原理,最终content字段的倒排索引会被更新成如下结构:

    词条 倒排列表项
    长安 [1]
    十二时 [1]
    十二 [1, 2]
    时辰 [1]
    十二生肖 [2]
    生肖 [2]

    3、

    前边已经添加了文档数据,同时也生成了倒排索引,接下来就是检索数据了。在这之前还有一个知识点需要了解,那就是词条索引(Term Index),词条索引一般只存储各个词条的前缀(第一个字符),它和字条字典对应。之所以需要词条索引,是因为词条字典一般都很大,不适合保存在内存中而是存储在磁盘中,检索数据时根据关键字的前缀匹配到词条索引,再根据词条索引定位到关键字在倒排索引的词条字典中大致的位置,然后进一步在词条字典中通过二分查找定位到具体的词条,这样避免了直接遍历词条字典来点位词条,大幅减少了磁盘的读取,提高了效率。

    定位到了词条,就能在倒排索引中找到对应的倒排列表项,进而就知道了对应的文档 id,有了文档 id 自然也就找到了文档,这也就是 ES 检索数据大致的原理。

    如下我们查询包含十二的文档数据:

    GET test/_search
    {
      "query": {
        "match": {
          "content": "十二"
        }
      }
    }
    

    由于我们创建索引库时指定了检索时关键字的分词模式是ik_smart,所以十二被分词后还是十二,再结合上边的原理,以十二为关键字最终可以查询到 id 为 1、2 的文档数据:

    这篇最好能结合Elasticsearch 中文分词器插件一起看,这样能更容易理解些。

    新手上路,不合理的地方还望大佬指点。

    相关文章

      网友评论

          本文标题:Elasticsearch 倒排索引

          本文链接:https://www.haomeiwen.com/subject/hpyfgktx.html