什么是倒排索引及 Elasticsearch 常用字段类型解析

发布于:2025-05-27 ⋅ 阅读:(74) ⋅ 点赞:(0)

引言

在全文搜索引擎中,倒排索引是核心的数据结构,它通过从文档中提取关键词并建立关键词到文档的映射关系,实现了高效的文本检索。本文将详细介绍倒排索引的组成与作用,并结合 Elasticsearch,解析其索引、文档、字段等基本概念及常见字段类型,帮助您深入理解搜索引擎底层机制及数据建模方法。

什么是倒排索引?

倒排索引是全文搜索引擎的核心数据结构,其主要作用是从文档中提取关键词,并建立关键词到文档的映射关系。这种结构与传统的正排索引(即文档到关键词的映射)相反,因此称为倒排索引。

注:Elasticsearch 索引中,只有字符串类型字段会创建倒排索引。

倒排索引主要组成部分

词典中的每个词汇作为一个键,每个键对应一个倒排列表。

词典(Term Dictionary)

包含所有在文档集合中出现的词汇,是一个按字母顺序排序的列表,其中每个词条(term)都指向一个倒排列表。

倒排列表(Posting List)

对于词典中的每个词汇,倒排列表是与其相关联的列表,该列表包含出现在文档集合中的这个词的所有文档ID。倒排列表不仅仅包括文档ID,还包含词频(词在某个文档中出现的次数)、位置列表(可选,词在某个文档中的位置)、其它信息(词在标题或正文中的位置,词在文档中的重要性等)。

索引、类型、文档和字段

索引

索引存储具有相似特性文档的集合。相当于MySQL中的数据库

类型

类型用于在同一个索引中将文档分类为不同类别。每个文档都有一个类型字段,指示其类别。从Elasticsearch 7.0版本开始,类型的概念被完全移除,一个索引只能包含一个类型。相当于MySQL中的表

文档

文档是Elasticsearch中的基本信息单元,类似于关系型数据库中的一行数据。每个文档都有一个唯一的ID,并存储为JSON格式。相当于MySQL中的行数据

字段

字段是文档中的属性或数据单元。每个字段都有一个名称和一个与之关联的值。相当于MySQL中的表字段

字段类型

字符串类型

text:用于全文搜索的文本数据。text类型的字段会被分词(tokenized)以便于搜索。

keyword:用于精确匹配的关键词数据。keyword类型的字段不会被分词,常用于过滤、排序和聚合操作。

数值类型

integer:32位有符号整数。

long:64位有符号整数。

float:32位浮点数。

double:64位浮点数。

half_float:使用16位存储浮点数,节省存储空间,用于对精度要求不高的数据。

scaled_float:将浮点数乘以一个预定义的缩放因子(scaling_factor)并存储为整数来提高数值存储的精度。这种方法在需要更高精度的十进制数表示时非常有用。下面示例是保存2位精度。

PUT /my_index
{
  "mappings": {
    "properties": {
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}
布尔类型

boolean:用于表示truefalse值。

日期类型

date:用于表示日期和时间。Elasticsearch支持多种日期格式。

复杂类型

object:用于表示嵌套的JSON对象结构,其内部字段会被扁平化(flatten)到顶层文档中。

nested:用于嵌套JSON对象,但它会将每个嵌套对象单独存储为一个隐藏的内部文档,从而保持嵌套关系的完整性。

#Json文档
{
  "user": {
    "name": "John",
    "tags": [
      {"key": "role", "value": "admin"},
      {"key": "location", "value": "US"}
    ]
  }
}

#使用object类型映射
PUT /my_index
{
  "mappings": {
    "properties": {
      "user": {
        "properties": {
          "name": { "type": "text" },
          "tags": {
            "properties": {
              "key": { "type": "keyword" },
              "value": { "type": "text" }
            }}}}}}}

#使用nested类型映射
PUT /my_index
{
  "mappings": {
    "properties": {
      "user": {
        "properties": {
          "name": { "type": "text" },
          "tags": {
            "type": "nested",
            "properties": {
              "key": { "type": "keyword" },
              "value": { "type": "text" }
            }}}}}}}

#object类型搜索,将匹配任何包含user.tags.key为role且user.tags.value为admin的文档,
#但不考虑它们是否在同一个tags对象中。
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.tags.key": "role" } },
        { "match": { "user.tags.value": "admin" } }
      ]
    }}}

#nested类型搜索,确保user.tags数组中同一个对象的key为role且value为admin的文档匹配。
GET /my_index/_search
{
  "query": {
    "nested": {
      "path": "user.tags",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.tags.key": "role" } },
            { "match": { "user.tags.value": "admin" } }
          ]
        }}}}}
地理类型

geo_point:用于表示地理空间中的一个点,即一个经纬度坐标。这个类型适合用来存储和查询简单的点数据,例如用户位置、商店位置等。

geo_shape:用于表示复杂的地理空间图形,如多边形、线、点集合等。这个类型适合用来存储和查询复杂的地理空间数据,例如国家边界、多边形区域等。


感谢您的阅读!如果文章中有任何问题或不足之处,欢迎及时指出,您的反馈将帮助我不断改进与完善。期待与您共同探讨技术,共同进步!