Elasticsearch-倒排索引

118 阅读5分钟

ElasticSearch介绍

Elasticsearch 是一个基于 Lucene 构建的开源、分布式、RESTful风格的搜索引擎。它提供了全文搜索和分析能力,并且能够处理大量数据。Elasticsearch 通常用于日志分析、全文搜索、操作情报、安全分析。

  1. 分布式:Elasticsearch 设计为分布式系统,可以轻松地扩展到数百台服务器,处理 PB 级别的数据。
  2. RESTful API:提供了一个 RESTful API,使得它可以通过 HTTP 请求进行操作,易于使用和集成。
  3. 实时搜索:Elasticsearch 提供了快速的搜索能力,可以实时地索引和搜索数据。

倒排索引

今天主要介绍他的核心基础,倒排索引,所谓的倒排索引其实是相对与MySql这种数据库来说的,所以为了更方便了解倒排索引的概念,我们对比着mysql来进行学习。

mysql正向索引

假设我们有一个简单的 MySQL 数据库表 books,用于存储书籍信息:

CREATE TABLE books (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    author VARCHAR(100),
    content TEXT
);

-- 插入两条测试数据
INSERT INTO books (title, author, content) VALUES
('MySQL 教程', '张三', 'MySQL 是一个流行的关系型数据库管理系统...'),
('Elasticsearch 简介', '李四', 'Elasticsearch 是一个基于 Lucene 的搜索引擎...');

在 MySQL 中,如果我们想要为 content 列创建一个索引以提高查询效率,我们可能会创建一个 B-tree 索引。这个索引会按照 content 列的值排序,mysql底层维护一个索引结构,并且每个值都会指向包含该值的行的物理位置(如磁盘上的偏移量),如果你创建了主键id的话,也可能是指向主键,没有主键则指向磁盘中的物理位置,或者是数据库内部使用的其他标识符,具体取决于数据库的实现。索引结构如下:

文档ID内容(content)
1MySQL 是一个流行的关系型数据库管理系统...
2Elasticsearch 是一个基于 Lucene 的搜索引擎...

这里的文档就是mysql数据库中对应的一行数据,在这种情况下,数据库会首先访问 context 索引,找到所有 context 包含"Elstaicsearch" 的记录,并获取它们的 id(或者其它行标识符)。然后,使用这些 id 直接定位到books表中相应的数据行。

Elasticsearch 倒排索引

同样的问题,看看Elasticsearch 是如何来解决的,同样的还是使用上面的表和数据,

{
  "mappings": {
    "properties": {
      "title": { "type": "text" },
      "author": { "type": "text" },
      "content": { "type": "text" }
    }
  }
}

插入相同的数据:

{
  "title": "MySQL 教程",
  "author": "张三",
  "content": "MySQL 是一个流行的关系型数据库管理系统,有很多教程,..."
}
{
  "title": "Elasticsearch 简介",
  "author": "李四",
  "content": "Elasticsearch 是一个基于 Lucene 的搜索引擎,有很多教程..."
}

在 Elasticsearch 中,当这些数据被索引时,它会为 content 字段自动创建一个倒排索引。这个倒排索引会将每个单词映射到包含该单词的文档列表,这里的单词是根据你文档中的内容分词得到的,具体得到的单词根据你采用的分词插件有所不同。现在对两个文档的context包含的内容进行分词:

单词文档ID
MySQL[1]
[1]
一个[1]
流行的[1]
关系型[1]
数据库[1]
管理系统[1]
Elasticsearch[2]
基于[2]
Lucene[2]
[2]
搜索引擎[2]
[1] [2]
很多[1] [2]
教程[1] [2]

在这个倒排索引中,每个词条(单词)都映射到一个包含该词条的文档列表。这就是为什么它被称为“倒排索引”,因为它“倒排”了文档和词条的关系,与传统的正向索引相反。传统的索引,每一个索引包含了自己文档中的全部词条。

Mysql与Elasticsearch的对比

这个对比表做得非常好,因为它清晰地展示了 MySQL 数据库和 Elasticsearch 之间的概念对应关系。通过这种方式,可以帮助理解两者之间的相似性和差异性。下面是对你提供的对比表的一些补充和解释:

MySQLElasticsearchES 描述
TableIndex索引
RowDocument文档(JSON 格式)
ColumnField字段(域)
SchemaMapping映射(结构)
SQLDSL (Query DSL)查询语言

解释

  1. Table <--> Index

    • MySQL 中的 Table 是存储数据的基本单元,而在 Elasticsearch 中,Index 也是基本的存储单元,它相当于 MySQL 中的“表”。
    • Elasticsearch 的索引通常包含文档集合,这些文档具有相似的属性或字段。
  2. Row <--> Document

    • MySQL 中的一行(Row)对应于一个具体的记录,而在 Elasticsearch 中,一个 Document 是一个 JSON 对象,代表一条记录。
    • 每个文档都可以有不同的结构,但通常在一个索引内的文档会有相似的结构。
  3. Column <--> Field

    • MySQL 中的 Column 是表中的一个字段,而在 Elasticsearch 中,Field 是文档中的一个属性或域。
    • 字段可以是简单的数据类型,如字符串、数字或日期,也可以是复杂的对象或数组。
  4. Schema <--> Mapping

    • MySQL 中的 Schema 定义了表的结构,包括列的名称、类型和约束等。
    • 在 Elasticsearch 中,Mapping 定义了索引中文档的结构,包括字段的名称、类型和索引选项等。
    • Elasticsearch 支持动态映射,即可以根据传入的文档自动推断映射结构。
  5. SQL <--> DSL (Query DSL)

    • MySQL 使用 SQL(Structured Query Language)作为查询语言。
    • Elasticsearch 使用 DSL(Domain-Specific Language),特别是查询 DSL,这是一种 JSON 格式的查询语言,用于构建复杂的查询条件。

总结

  • 正向索引:每个文档都有一个词条列表,列出了该文档中包含的所有词条。在 MySQL 中,这通常通过 B-tree 索引实现。
  • 倒排索引:每个词条都映射到一个包含该词条的文档列表。在 Elasticsearch 中,这是通过倒排索引实现的,以提高全文搜索的效率。