第3章:核心概念解析

3.1 索引(Index)结构与原理

3.1.1 什么是索引?

索引是全文检索系统的核心数据结构,用于加速文档搜索。Whoosh 使用 倒排索引(Inverted Index)技术,它将文档中的每个词(term)映射到包含该词的文档列表。

示例

文档1: "Python 是一门编程语言"
文档2: "Python 用于数据分析和机器学习"

倒排索引:
Python  → [文档1, 文档2]
编程语言 → [文档1]
数据分析 → [文档2]
机器学习 → [文档2]

搜索时只需查询关键词对应的文档列表,无需扫描全部文档,因此查询速度极快。

3.1.2 Whoosh 索引结构

Whoosh 索引由以下部分组成:

  • Segments(段):索引的物理存储单元,包含多个文档的数据
  • Terms(词项):经过分析器处理的单词,用于建立倒排索引
  • Postings( postings 列表):每个词对应的文档列表及位置信息
  • Stored Fields(存储字段):直接存储的原始字段值,用于结果展示

索引文件组成

index_dir/
├─ _0.toc          # 段信息
├─ _0.terms        # 词项字典
├─ _0.postings     # 倒排列表
├─ _0.stored       # 存储字段
└─ _0.lock         # 写锁

3.1.3 索引创建与打开

Whoosh 支持两种索引模式:

1. 创建新索引

from whoosh.index import create_in
ix = create_in("index_dir", schema)

2. 打开已有索引

from whoosh.index import open_dir
ix = open_dir("index_dir")

3.1.4 索引的生命周期

  • 创建:首次建立索引文件
  • 更新:通过 writer.add_document()writer.update_document() 修改
  • 合并:多个段合并优化,减少文件碎片
  • 删除:通过 writer.delete_document() 标记删除,定期清理

3.2 模式(Schema)设计基础

3.2.1 什么是 Schema?

Schema 定义了索引中每个文档的字段类型、存储方式和索引策略。类似于数据库的表结构设计。

Schema 的核心作用

  1. 类型定义:指定字段的数据类型(文本、数值、日期等)
  2. 存储策略:决定字段是否存储到索引中
  3. 分析器绑定:为文本字段指定分词规则
  4. 唯一约束:设置字段的唯一性,用于去重

3.2.2 Schema 定义示例

from whoosh.fields import Schema, TEXT, ID, NUMERIC, DATETIME

schema = Schema(
    title=TEXT(stored=True),              # 存储并索引
    content=TEXT(stored=False),           # 仅索引不存储
    path=ID(stored=True, unique=True),    # 唯一标识
    size=NUMERIC(stored=True),             # 数值字段
    modified=DATETIME(stored=True)         # 日期字段
)

3.2.3 Schema 设计原则

1. 合理选择存储字段

  • stored=True:需要直接读取字段值(如标题、摘要)
  • stored=False:仅用于搜索,不直接展示(如全文内容)

2. 根据查询需求选择字段类型

  • 精确匹配 → ID、KEYWORD
  • 全文搜索 → TEXT
  • 范围查询 → NUMERIC、DATETIME
  • 状态标记 → BOOLEAN

3. 考虑索引更新频率

  • 频繁更新的字段单独设置,减少索引合并开销
  • 静态字段与动态字段分离设计

4. 预留扩展空间

  • Schema 一旦创建,字段类型不可更改(可通过重建索引解决)
  • 设计时要考虑未来的查询需求

3.3 文档(Document)与字段(Field)

3.3.1 什么是文档?

文档是索引的基本单位,类似于数据库中的一行记录。每个文档由多个字段(Field)组成,每个字段对应 Schema 中定义的一个字段类型。

文档示例

{
    "title": "Python 全文检索入门",
    "content": "Whoosh 是一个纯 Python 实现的全文检索库...",
    "path": "/docs/python_whoosh.txt",
    "size": 1024,
    "modified": datetime(2024, 1, 1)
}

3.3.2 字段的特性

1. 索引与存储

  • indexed:字段是否参与索引(默认为 True)
  • stored:字段是否存储原始值(默认为 False)

2. 向量化

  • 文本字段会被分析器分词,生成多个词项
  • 非文本字段直接作为整体参与索引

3. 独特性

  • unique=True:确保字段值在所有文档中唯一
  • 用于文档的更新和删除操作

3.3.3 文档操作

添加文档

writer = ix.writer()
writer.add_document(
    title=u"文档标题",
    content=u"文档内容",
    path=u"/docs/doc1.txt"
)
writer.commit()

更新文档(基于唯一字段):

writer = ix.writer()
writer.update_document(
    path=u"/docs/doc1.txt",  # 基于唯一字段更新
    content=u"新的内容"
)
writer.commit()

删除文档(基于文档编号):

writer = ix.writer()
writer.delete_document(doc_num)  # doc_num 为文档索引号
writer.commit()

3.4 字段类型(Field Types)详解

Whoosh 提供多种字段类型,适用于不同的数据场景:

3.4.1 文本类型

TEXT:全文搜索字段

from whoosh.fields import TEXT

field = TEXT(
    stored=True,              # 是否存储
    analyzer=StandardAnalyzer(),  # 分词器
    phrase=True,              # 支持短语查询
    vector=None,              # 词频向量
    spelling=False,           # 拼写检查
    sortable=False            # 可排序
)
  • 用途:标题、摘要、正文等需要全文检索的字段
  • 特点:支持分词、短语查询、模糊匹配

3.4.2 标识类型

ID:唯一标识字段

from whoosh.fields import ID

field = ID(stored=True, unique=True)
  • 用途:文件路径、URL、唯一编号
  • 特点:不分词,精确匹配,可设置唯一性

3.4.3 关键字类型

KEYWORD:不分词的文本字段

from whoosh.fields import KEYWORD

field = KEYWORD(
    stored=True,
    commas=False,      # 是否使用逗号分隔
    lowercase=False,   # 是否转小写
    sortable=False
)
  • 用途:标签、分类、状态标记
  • 特点:整体匹配,支持多值(用逗号分隔)

3.4.4 数值类型

NUMERIC:数值字段

from whoosh.fields import NUMERIC

field = NUMERIC(
    stored=True,
    numtype=int,       # int/float/decimal
    signed=True,
    sortable=True,
    default=None
)
  • 用途:价格、数量、评分
  • 特点:支持范围查询、排序

3.4.5 日期时间类型

DATETIME:日期时间字段

from whoosh.fields import DATETIME

field = DATETIME(
    stored=True,
    sortable=True,
    default=None
)
  • 用途:创建时间、修改时间、发布日期
  • 特点:支持范围查询、时间区间筛选

3.4.6 布尔类型

BOOLEAN:布尔值字段

from whoosh.fields import BOOLEAN

field = BOOLEAN(stored=True)
  • 用途:是否公开、是否置顶
  • 特点:取值为 True/False

3.4.7 其他类型

LIST:列表字段(存储多个值)

from whoosh.fields import LIST, TEXT

field = LIST(TEXT, stored=True)

STORED:仅存储字段(不参与索引)

from whoosh.fields import STORED

field = STORED()

3.4.8 字段类型选择指南

数据类型 推荐字段类型 示例
全文内容 TEXT 文章正文、评论
精确标识 ID 文件路径、UUID
标签/分类 KEYWORD 标签列表、分类
数值 NUMERIC 价格、评分
日期时间 DATETIME 创建时间、发布日期
状态标记 BOOLEAN 是否启用
仅存储 STORED 原始内容、二进制数据

本章小结

本章我们深入学习了 Whoosh 的核心概念:

  1. 索引结构与原理:理解倒排索引的工作机制,掌握索引的创建、更新与维护
  2. Schema 设计基础:学习如何定义合理的字段结构,平衡存储与索引需求
  3. 文档与字段:理解文档的组成和字段的特性,掌握增删改操作
  4. 字段类型详解:熟悉各种字段类型的适用场景,能够根据需求选择合适类型

掌握这些核心概念后,你将能够在第4章中动手创建第一个全文索引,并在第5、6章中实现各种查询功能。

« 上一篇 环境配置与安装 下一篇 » 创建第一个全文索引