Elasticsearch 索引是什么?

info-retrieval-blog-720x420-v2.jpeg

在技术领域索引这个词已经用得太多了。如果您要问开发人员什么是索引,他们大多数人都可能会告诉您,索引通常是指关系数据库 (RDBMS) 中与表相关联的一种数据结构,可以提高数据检索操作的速度。

那么,Elasticsearch® 索引又是什么呢?Elasticsearch 索引是一个逻辑命名空间,其中包含一系列的文档,每个文档是一系列的字段,而字段又是包含数据的键值对。

Elasticsearch 索引与关系数据库有何不同?

Elasticsearch 索引与关系数据库中的索引不同。如果将 Elasticsearch 集群视为一个数据库,它可以包含许多索引,您可以将它们看作是一个表,在每个索引内,有许多文档。   

  • RDBMS => 数据库 => 表 => 列/行
  • Elasticsearch => 集群 => 索引 => 分片 => 带有键值对的文档

虽然 Elasticsearch 存储的是 JSON 文档,但您可以非常灵活地向索引中输入各种类型的内容。使用大量可用的集成Beats,即可快速完成部署并开始运行。或者,您还可以更进一步,借助采集管道Logstash® 附带的大量处理器和插件,用来定义自己的 ETL 流程。

与关系数据库的另一个不同之处在于,您无需预先定义任何模式便可导入数据。建议先从动态类型入手,这是快速开始使用或解释说明文档中意外字段的绝佳方式。然后,待一切准备就绪后,再切换到固定模式来提高性能。 

运行时字段是另一个值得关注的功能,可让您在读取或写入时检查模式。这些运行时字段可以添加到现有文档并用来派生新字段,也可以在查询时创建运行时字段。它们可看作是使用能够读取文档源代码的脚本计算的值。

准备好在实际操作中体会它们的区别了吗?请立即在 Elastic Cloud 上通过试用帐户开始免费试用吧。

数据如何与 Elasticsearch 用户友好型 API 进行交互

Elasticsearch 提供了一个遵循 REST 标准且基于 JSON 的 API,用于与文档数据交互。通过向适当的集群终端发送 HTTP 请求,您可以索引、搜索、更新和删除文档。这些类似于 CRUD 的操作,可以在单个文档级别执行,也可在索引级别本身执行。如果您愿意,也可以使用特定语言的客户端库来代替直接 REST。
下面的示例在名为 playwrights 的索引中创建了一个文档,分配的 document_id 为 1。请注意,我们不需要创建任何模式或进行预先配置,只需插入数据即可。

POST /playwrights/_doc/1
{
  "firstname": "William",
  "lastname": "Shakespeare"
}

我们可以根据需要进一步添加文档和字段,而关系数据库却无法轻松做到这一点。

POST /playwrights/_doc/2
{
  "firstname": "Samuel",
  "lastname": "Beckett",
  "year_of_birth": 1906
}

现在,我们可以使用搜索终端查询出所有文档。

GET /playwrights/_search
{
    "query": {
        "match_all": {}
    }
}

或者,我们也可以查询具体的出生年份。

GET /playwrights/_search
{
    "query": {
        “match": {
            “year_of_birth": 1906
        }
    }
}

除了基本查询功能外,Elasticsearch 还提供了多种高级搜索功能,比如模糊匹配、词干提取、相关性评分、高亮显示和词汇切分(可将文本拆分成更小的组成部分,也就是词元)。在大多数情况下,这些词元是单个字词,但也有很多不同的分词器可供选择。

为什么非规范化数据是加快数据检索的关键?

在关系数据库中,规范化通常适合用来消除数据冗余和确保数据一致性。例如,您可能会针对客户、产品和订单分别设置不同的表。 

在 Elasticsearch 中,去规范化是一种常见的做法。您可以将所有相关信息存储在单个 JSON 文档中,而不是将数据拆分到多个表中。与在订单文档中保存指向单独产品和客户索引的外键所不同的是,这个订单文档中将会包含客户信息和产品信息。这样,在搜索操作过程中,Elasticsearch 便可更快、更高效地检索数据。通常而言,存储成本可能比联接数据的计算成本更低。

Elasticsearch 如何确保分布式系统的可扩展性?

每个索引都有一个唯一可识别的名称,并划分为一个或多个分片,这些分片是索引的较小子集,可在所有 Elasticsearch 节点集群中进行并行处理和分布式存储。 分片包含一个主分片和一个副本分片,副本分片提供数据的冗余副本,可以防止出现硬件故障,并提高为搜索或检索文档等读取请求提供服务的能力。

向集群中添加更多节点,即可提高索引和搜索的能力,而关系数据库却无法轻松做到这一点。

回到上面的 playwrights 示例,如果我们运行下面的代码,就可以看到 Elasticsearch 自动推断出的类型映射,以及索引已经分配的分片数和副本数。

GET /cn/playwrights/

使用 Elasticsearch 可以索引哪些类型的数据?

Elasticsearch 可以索引多种类型的数据,首先是文本,其次还包括数字和地理位置数据。它还可以存储用于相似性搜索的稠密矢量。下面让我们依次来看一看这些数据。

用于文本/词汇搜索的倒排索引

Elasticsearch 还会为特定字段类型选用最佳的底层数据结构。例如,文本会进行分词,然后存储在倒排索引中;倒排索引是一种结构,用于列出任何文档中出现的每个唯一词元,并识别有每个单词出现的所有文档。

下表显示了倒排索引的一般构成。我们可以看到,如果搜索“London”一词,就会发现这个词在索引中出现在六个不同的文档中。正是通过这种倒排索引,我们才能够非常快地执行文本查询。

词元

文档 ID

London

1,3,8,12,23,88

Paris

1,12,88

Madrid3,8,12
Berlin12,23

用于进行高效空间分析的数字和地理位置搜索功能

数字和地理位置数据将存储在 BKD 树(也称为 Block KD-Tree 索引)中,这是一种在工程应用中使用的数据结构,可对多维数据进行高效的空间索引和查询。它可将数据点组织成块,实现在大型数据集中进行快速范围搜索和最近邻查询,是工程师处理空间数据分析和优化的重要工具。

利用 NLP 进行矢量/语义搜索

您或许听说过矢量搜索,但矢量搜索是什么呢?矢量搜索引擎也称为矢量数据库、语义搜索或余弦搜索,可用于查找给定(矢量化)查询的最近邻。矢量搜索的强大之处在于,它能够发现并非精确匹配文本的相似文档,就像上述倒排索引示例所要求的那样;而且它可以使用矢量来描述某种程度的相似性。 

自然语言处理 (NLP) 社区开发了一项名为文本嵌入的技术,能够将词语和句子编码为数字矢量。这些“矢量表示形式”旨在采集文本的语言学内容,并可用来评估查询内容和文档之间的相似性。

矢量搜索的一些常见用例如下: 

  • 回答问题
  • 为以前回答过的问题查找答案,在这种情况下,提出的问题在文本形式上相似但不完全相同 
  • 进行推荐 — 例如,音乐应用程序根据您的偏好来查找类似的歌曲  

所有这些用例都利用了具有数万个维度的矢量,为准确的相似性评估和有针对性的推荐提供了全面的数据表示形式。  

Elasticsearch 通过 dense_vector 文档类型支持矢量搜索,并能够在文档中的矢量和转换为矢量后的搜索词之间运行相似性搜索。 

对于那些想要更深入研究生成式 AI 的用户,我们还提供了 Elasticsearch Relevance Engine™ (ESRE),旨在为基于人工智能的搜索应用程序提供强大支持。ESRE 为开发人员提供了一整套成熟的检索算法,并能够与大型语言模型进行集成。

立即试用!

正如您所看到的,自 Elastic 联合创始人兼首席技术官 Shay Banon 第一次为妻子编写食谱搜索引擎以来,Elasticsearch 索引已经取得了长足的发展。您还可以继续探索更多功能,不妨先在 Elastic Cloud 上创建一个试用帐户,几分钟内就可完成部署并开始运行。此外,还可参加 Elasticsearch 入门网络研讨会。

最初发布于 2013 年 2 月 24 日;更新于 2023 年 7 月 17 日。