【Elasticsearch】正排索引、倒排索引(含实战案例)

1.正排索引与倒排索引

1.1 正排索引(Forward Index)

正排索引是一种从 文档 ID文档内容 的映射结构,它存储了文档的原始数据。

特点

  • 文档 ID → 文档内容
  • 类似于传统数据库的行存储
  • 适合通过文档 ID 快速获取完整文档内容

示例

文档ID: 1 → { "title": "Elasticsearch Guide", "content": "Elasticsearch is a search engine", "author": "John" }
文档ID: 2 → { "title": "Big Data", "content": "Big data is a large volume of data", "author": "Alice" }

正排索引的主要使用场景

  • 获取搜索结果的具体内容
    • 场景:显示搜索结果列表
    • 示例:返回搜索到的前 10 篇文章的标题和摘要
    • 原理:通过文档 ID 从正排索引获取原始字段值
  • 排序和脚本计算
    • 场景:按字段值排序或计算
    • 示例:按价格排序商品,或计算折扣价
    • 原理:需要访问字段原始值进行计算
  • 高亮显示
    • 场景:显示搜索关键词的上下文
    • 示例:在搜索结果中高亮显示匹配的关键词
    • 原理:需要知道字段原始内容和词项位置信息
  • 字段值聚合
    • 场景:基于字段值的统计分析
    • 示例:计算平均价格、价格区间分布
    • 原理:需要访问字段的原始数值

1.2 倒排索引(Inverted Index)

倒排索引是一种从 词项文档 ID 的映射结构,是搜索引擎的核心数据结构。

特点

  • 词项 → 文档 ID 列表
  • 支持快速查找包含特定词项的文档
  • 包含词频、位置等信息

示例

"elasticsearch" → [1](出现在文档 1)
"search" → [1]
"big" → [2]
"data" → [2]
"engine" → [1]
"guide" → [1]

倒排索引的主要使用场景

  • 全文搜索
    • 场景:用户输入关键词搜索内容
    • 示例:电商平台搜索 “无线蓝牙耳机
    • 原理:倒排索引快速定位包含这些关键词的商品
  • 精确值查询
    • 场景:查找特定值的文档
    • 示例:查找 status=active 的用户
    • 原理:倒排索引直接定位具有该精确值的文档
  • 多条件组合查询
    • 场景:复杂过滤和搜索
    • 示例:搜索 “价格低于 500 元且评分 4 星以上的手机
    • 原理:倒排索引高效合并多个条件的文档 ID 集合
  • 聚合分析
    • 场景:基于词项的统计分析
    • 示例:统计最常出现的错误日志关键词
    • 原理:倒排索引已经组织好了词项与文档的关系

1.3 区别对比

特性正排索引倒排索引
映射方向文档 ID → 文档内容词项 → 文档 ID 列表
主要用途获取完整文档内容快速查找包含词项的文档
存储内容原始文档数据分词后的词项及位置信息
查询效率通过 ID 查询快全文检索快
更新代价高(需要重建索引)高(需要重新计算词项映射)
典型应用获取搜索结果的具体内容执行搜索查询

1.4 实际应用中的协同工作示例

  • 搜索阶段:使用倒排索引快速找到匹配的文档 ID。
  • 获取阶段:使用正排索引获取匹配文档的完整内容。

例如搜索 search engine

  • 倒排索引找到 search 匹配文档 1engine 匹配文档 1 → 结果 [1]
  • 正排索引获取文档 1 的完整内容返回给用户。

这种组合使得 Elasticsearch 既能高效搜索又能快速返回完整文档内容。

电商搜索案例

  • 用户搜索 “男士 运动鞋 耐克”(使用倒排索引快速定位匹配商品)
  • 系统需要:
    • 按价格排序(使用正排索引获取价格字段)
    • 显示商品图片、名称、价格(使用正排索引获取这些字段)
    • 高亮搜索关键词(结合倒排索引的位置信息和正排索引的原始内容)

1.5 性能优化考虑

  • 禁用正排索引:对于不用于排序、聚合或脚本的字段,可以设置 "doc_values": false 节省空间。
  • 字段数据加载:正排索引数据在首次用于聚合 / 排序时需要加载到内存,可能影响性能。
  • 存储策略_source 字段存储完整文档(类似正排索引),而倒排索引只存储分析后的词项。

理解这两种索引的不同用途,可以帮助我们更好地设计 Elasticsearch 的映射和查询,优化搜索性能和资源使用。

2.Kibana 实际操作案例

下面我将通过一个完整的电商商品搜索案例,演示如何在 Kibana 中实际操作并观察两种索引的工作方式。

2.1 案例准备:创建商品索引

2.1.1 创建索引并定义映射

在 Kibana Dev Tools 中执行:

PUT /products
{
  "mappings": {
    "properties": {
      "name": { 
        "type": "text",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "description": { "type": "text" },
      "price": { "type": "double" },
      "stock": { "type": "integer" },
      "brand": { 
        "type": "keyword",
        "doc_values": false  // 特意关闭正排索引
      },
      "tags": { "type": "keyword" },
      "created_at": { "type": "date" }
    }
  }
}

在这里插入图片描述

2.1.2 插入测试数据

POST /products/_bulk
{"index":{}}
{"name":"Wireless Bluetooth Headphones","description":"High-quality wireless headphones with noise cancellation","price":199.99,"stock":50,"brand":"Sony","tags":["electronics","audio"],"created_at":"2023-01-15"}
{"index":{}}
{"name":"Running Shoes Men","description":"Lightweight running shoes for men, size 9-12","price":89.99,"stock":120,"brand":"Nike","tags":["sport","footwear"],"created_at":"2023-02-20"}
{"index":{}}
{"name":"Smart Watch Pro","description":"Waterproof smartwatch with heart rate monitor","price":259.99,"stock":30,"brand":"Apple","tags":["electronics","wearable"],"created_at":"2023-03-10"}

在这里插入图片描述

2.2 实际操作演示

2.2.1 场景 1:倒排索引应用(全文搜索)

GET /products/_search
{
  "query": {
    "match": {
      "description": "wireless waterproof"
    }
  }
}

观察点

  • 倒排索引快速找到包含 wirelesswaterproof 的文档。
  • 结果会包含耳机和智能手表,但相关性更高的会排在前面。

在这里插入图片描述

2.2.2 场景 2:正排索引应用(排序与字段获取)

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    { "price": "asc" }
  ],
  "_source": ["name", "price"],
  "size": 2
}

观察点

  • 使用正排索引获取 price 字段值进行排序。
  • 只返回 nameprice 字段(从正排索引获取)。

在这里插入图片描述

2.2.3 场景 3:倒排+正排结合(聚合分析)

GET /products/_search
{
  "size": 0,
  "aggs": {
    "price_stats": {
      "stats": { "field": "price" }  // 需要正排索引
    },
    "popular_tags": {
      "terms": { "field": "tags" }  // 使用倒排索引
    }
  }
}

观察点

  • price_stats 聚合需要正排索引计算统计值。
  • popular_tags 聚合直接使用倒排索引的词项频率。

在这里插入图片描述

2.2.4 场景 4:禁用正排索引的影响

GET /products/_search
{
  "query": {
    "term": {
      "brand": "Nike"
    }
  }
}

// 尝试按 brand 排序会报错
GET /products/_search
{
  "sort": [
    { "brand": "asc" }
  ]
}

观察点

  • 搜索可以工作(使用倒排索引)。
  • 排序失败因为 brand 字段设置了 "doc_values": false

在这里插入图片描述
在这里插入图片描述

2.3 使用 Kibana Discover 验证

  • 打开 Kibana → Discover
  • 选择 products 索引模式
  • 尝试不同搜索:
    • 搜索框输入waterproof(倒排索引)
      在这里插入图片描述

    • 点击 price 字段的排序箭头(正排索引)
      在这里插入图片描述

    • 点击 tags 字段查看热门值(倒排索引)
      在这里插入图片描述

2.4 性能对比实验

2.4.1 倒排索引效率测试

GET /products/_search
{
  "query": {
    "term": {
      "tags.keyword": "electronics"
    }
  }
}

在这里插入图片描述

2.4.2 正排索引效率测试

GET /products/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 100
      }
    }
  }
}

在这里插入图片描述

对比观察

  • 在 Kibana 的右侧可以查看请求耗时。
  • 大数据量时差异会更明显。

这个案例完整展示了两种索引在实际查询中的不同应用场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G皮T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值