RediSearch `FT.CREATE` 完全参数指南 & HASH/JSON 双写实战

发布于:2025-06-23 ⋅ 阅读:(16) ⋅ 点赞:(0)

1、索引与 Schema 速概

  • 索引 (index) —— 倒排、前缀、向量、Geo … 元数据集合
  • Schema —— 索引蓝图:定义字段、类型、权重、排序及存储策略
  • FT.CREATE —— 创建索引命令,分「索引级参数」和「字段级参数」两层

2 、FT.CREATE 语法模板

FT.CREATE <index>
    ON HASH|JSON
    PREFIX <n> <pfx1> [pfx2 …]
    [FILTER '<expr>']
    [其他索引级选项 …]
SCHEMA
    <field> [AS <alias>] <type> [字段级选项 …]
    ...

官方命令文档详见 Redis Docs ([redis.io][1])

3、索引级参数总览

参数 功用 典型用法
`ON HASH JSON` 目标数据结构 ON HASH
PREFIX n pfx… 键前缀过滤 PREFIX 2 prod: blog:
FILTER 'expr' 条件索引 FILTER '@status == "PUBLISHED"'
LANGUAGE lang / LANGUAGE_FIELD fld 默认/动态语言 LANGUAGE zh
SCORE n / SCORE_FIELD fld 文档相关度基线 SCORE 0.5
PAYLOAD_FIELD fld 自定义二进制 payload A/B Rank 用
TEMPORARY sec N 秒后自动删除 临时分析索引
SKIPINITIALSCAN 跳过历史数据 热流量场景
MAXTEXTFIELDS 支持 > 32 TEXT 巨型 JSON
内存优化族
`NOOFFSETS
NOHL NOFIELDS NOFREQS` 关闭偏移/高亮/字段位图/词频 只做过滤
`STOPWORDS cnt … 0` 自定义/禁用停用词 STOPWORDS 0

4、字段类型

类型 用途 & 特性
TEXT 倒排全文检索;支持权重/词干/语音匹配
TAG 离散标签;SEPARATOR 自定义分隔符
NUMERIC 范围过滤、排序
GEO 圆形半径查询
VECTOR 向量 KNN / Range(≥ 2.4,需 DIALECT 2+)
GEOSHAPE 多边形 & 点 WKT 查询(2.8 新增)([redis.io][2])

5、字段级选项

选项 适用 说明
WEIGHT w TEXT 相关度乘子
SORTABLE [UNF] TEXT TAG NUMERIC GEO 低延时排序;UNF 保留大小写 ([redis.io][1])
NOSTEM TEXT 关词干化
PHONETIC dm:xx TEXT 英/法/葡/西语发音
SEPARATOR ';' TAG 自定义分隔符
CASESENSITIVE TAG 区分大小写
WITHSUFFIXTRIE TEXT TAG 高效中/后缀、通配符
NOINDEX 任意 仅存储/排序不倒排
INDEXEMPTY / INDEXMISSING 任意 索引空值/缺失值(≥ 2.10)

6、版本演进关键点

版本 新能力
2.4 向量 KNN 查询引入
2.6 / DIALECT 3 JSON 多值字段返回结构、向量 Range 可多次
2.8 GEOSHAPE 字段 + WITHIN/CONTAINS 多边形检索 ([redis.io][2])

7、典型 Schema 范例

7.1 带权重、排序与标签
FT.CREATE blog-idx ON HASH PREFIX 1 blog:post:
SCHEMA
  title        TEXT    WEIGHT 5.0
  content      TEXT
  author       TAG
  created_date NUMERIC SORTABLE
  views        NUMERIC
7.2 自定义分隔符 TAG
FT.CREATE books-idx ON HASH PREFIX 1 book:details
SCHEMA
  title       TEXT
  categories  TAG SEPARATOR ";"
7.3 一字段两种索引
FT.CREATE multi-idx ON HASH PREFIX 1 inventory:
SCHEMA
  sku AS sku_text TEXT
  sku AS sku_tag  TAG SORTABLE
7.4 JSON + JSONPath
FT.CREATE prodjs-idx ON JSON
SCHEMA
  $.title       AS title       TEXT
  $.categories  AS categories  TAG
  $.emb_vector  AS vector      VECTOR FLAT 6 TYPE FLOAT32 DIM 384 DISTANCE_METRIC COSINE

8、Schema 设计最佳实践

  1. 按需建索引:无查询需求字段可 NOINDEX / 不纳入 Schema
  2. 权重分级:标题、关键词拉高 WEIGHT,正文保持默认 1
  3. SORTABLE 谨慎:仅业务排序字段添加,否则内存倍增
  4. TAG 代替 TEXT 精确过滤:城市/状态/ID 等离散值
  5. FILTER 精准控制:索引前裁剪垃圾数据,减少写放大
  6. 统一前缀PREFIX 限定业务 Key,避免误索引其他模块

9、Hash + JSON 双写部署方案

场景:电商商品——Hash 做高速计数/库存;JSON 做复杂检索/推荐。

在这里插入图片描述

9.1 索引策略

方案 描述 适用
双索引(推荐) idx_hash ON HASH + idx_json ON JSON;用 FT.ALIASADD 做读写别名 读写职责分离,Schema 灵活
JSON 主索引 + Hash 计数镜像 JSON 索引所有检索字段;Lua/Streams 异步写 Hash 计数 检索强需求,计数可弱一致
反向镜像(少见) 以 Hash 为主,定时刷新 JSON 影子 仅历史分析场景

9.2 代码示例(Go-redis)

pipe := rdb.TxPipeline()
// Hash: 秒级计数
pipe.HSet(ctx, "prod:1001", "price", 199, "stock", 8)
// JSON: 搜索主体
pipe.Do(ctx, "JSON.SET", "prodjs:1001", "$",
        `{"title":"Alpha Phone","desc":"6.7\" AMOLED",`+
        `"attrs":{"ram":8,"rom":256},"vector":`+string(vecBlob)+`}`)

_, err := pipe.Exec(ctx)

搜索 Top-10 最近邻 + 价格过滤:

FT.SEARCH idx_json \
  "@price:[100 300]=>[KNN 10 @vector $qvec]" \
  PARAMS 2 qvec $queryVector DIALECT 3

9.3 一致性 & 性能要点

  1. 事务 or 幂等重试:TxPipeline + 重试
  2. 内存评估:Hash + JSON 两份数据;NOFIELDS/NOOFFSETS 减负
  3. 可观测性FT.INFO 监控 sortable_values_size_mb 等指标 ([redis.io][3])
  4. 索引热切换:新建索引 → FT.ALIASADD newFT.ALIASUPDATE prod_read 零停机
  5. Active-Active:JSON 已实现 CRDT;Hash 需应用幂等逻辑防冲突

10 | 常见坑与调优

症状 排查 & 解决
内存暴涨 检查 SORTABLE / 长文本 TEXT;用 FT.INFO 查看各 size_mb
全表扫描慢 查询含大量 *foo*;加 WITHSUFFIXTRIE、限制 MAXEXPANSIONS
负查询 CPU 高 纯负 -term 小命中 → 等同遍历全库;改为正向查询 + 额外条件
schema 变更影响线上 使用新索引 + ALIAS 逐步切流;或 FT.ALTER 限制改动维度
Prefix 错误 忘记带冒号导致全库 Key 入索引

11、总结

  • Schema 决定索引成败:理解每个字段类型与参数含义至关重要
  • 双写不是洪水猛兽:得当的事务、事件流 + RediSearch 实时索引即可平滑运行
  • 主动监控 & 热切换:用 FT.INFOFT.ALIAS* 工具化运维,才能保证线上稳定

网站公告

今日签到

点亮在社区的每一天
去签到