Redis 向量查询怎样组合标签过滤与距离排序
来源:17golang原创
时间:2026-10-09 22:15:35 290浏览 收藏
做 Redis 向量检索时,业务条件往往不是“全库找最像”,而是“只在某个标签范围内找最像”。例如知识库要先限定 category=manual,再按 embedding 距离取前 5 条。稳定的写法是把标签条件放进 FT.SEARCH 的括号过滤表达式,再接 KNN,用 PARAMS 传入二进制查询向量,最后用距离别名和 SORTBY ... ASC 固定排序。
官方地址:https://redis.io/docs/latest/develop/ai/search-and-query/query/vector-search/
- 标签过滤放在
(...)中,=>后连接向量查询,避免把业务范围交给应用层再过滤。 - KNN 解决固定 top-k;需要距离上限时改用
VECTOR_RANGE,两者都使用DIALECT 2。 - 距离字段必须显式命名并参与排序;
$SHARD_K_RATIO只对 Redis Cluster 有意义。
先把标签和向量放进同一个索引
本文假设文档至少包含三个字段:业务标签 category、可选的标题或摘要,以及向量字段 embedding。标签要按 TAG 方式建索引,向量的维度、类型和距离度量必须与生成 embedding 的模型保持一致。下面的命令只是一个最小结构示意,向量字节由应用生成,不要把示例中的占位串当成真实向量。
# 创建一个同时支持标签过滤和向量检索的索引
FT.CREATE idx:docs ON HASH PREFIX 1 "doc:" SCHEMA \
category TAG SEPARATOR "," \
title TEXT \
embedding VECTOR HNSW 6 TYPE FLOAT32 DIM 768 DISTANCE_METRIC COSINE
# 写入文档时,embedding 应是模型输出的 FLOAT32 二进制内容
HSET doc:001 category "manual" title "Redis 查询手册" embedding ""
这里的重点不是索引参数越多越好,而是让过滤字段与向量字段属于同一查询模型。若标签没有按 TAG 建模,查询语法就不能按标签精确缩小候选;若 DIM 或距离度量不匹配,结果即使能返回,也没有可靠的业务含义。
先用标签缩小候选,再执行 KNN
KNN 适合“在满足条件的文档中固定取前 k 个”。Redis 的组合查询可以把 (@category:{manual}) 放在前面,=> 后接 [KNN 5 @embedding $query_vector AS distance]。这样标签是搜索范围,向量距离才是排序依据。
# 只在 manual 标签内找最相近的 5 条文档
FT.SEARCH idx:docs \
"(@category:{manual})=>[KNN 5 @embedding $query_vector AS distance]" \
PARAMS 2 query_vector "" \
SORTBY distance ASC \
RETURN 3 distance title category \
DIALECT 2
PARAMS 2 后面是参数名和参数值,数量写错会导致查询无法正确绑定。AS distance 给向量分数起了稳定名字,随后才能用 SORTBY distance ASC 排序。返回字段也尽量收窄,先拿距离、标题和标签,正文或大字段按需二次读取。

距离字段、排序与验收边界
“返回了 5 条”并不等于查询正确,至少要核对三件事:结果是否都带目标标签、距离是否按升序排列、返回数量是否受 top-k 控制。还要分清两种需求:
| 需求 | 查询方式 | 判断重点 |
|---|---|---|
| 固定返回前 k 条 | KNN | 关注 top-k、距离排序与候选范围 |
| 只接受距离不超过阈值的结果 | VECTOR_RANGE | 关注半径、距离别名与分页 |
| Redis Cluster 下调节召回与性能 | SHARD_K_RATIO | 只在集群环境有作用 |
当业务是“相似度至少达到某个标准”,不要先取很大的 KNN 再在应用层猜阈值,可以使用 VECTOR_RANGE,并通过 $YIELD_DISTANCE_AS 导出距离:
# 只返回 manual 标签中距离不超过 0.35 的结果,并按距离升序
FT.SEARCH idx:docs \
"@category:{manual} @embedding:[VECTOR_RANGE 0.35 $query_vector]=>{$YIELD_DISTANCE_AS: distance}" \
PARAMS 2 query_vector "" \
SORTBY distance ASC RETURN 3 distance title category DIALECT 2
如果部署在 Redis Cluster,可以在 KNN 后设置 $SHARD_K_RATIO,让每个分片多取一些候选再汇总;它是召回与性能之间的调节旋钮,单机 Redis 不会因为写上它就获得额外效果。

用一张清单验收组合查询
- 先用一个已知标签过滤,确认结果不会混入其他类别。
- 把
KNN 5改成KNN 1,确认返回数量和距离字段仍然存在。 - 固定同一个查询向量重复请求,确认距离排序稳定;不要用文档返回顺序代替显式排序。
- 将半径调小,确认
VECTOR_RANGE会自然减少结果,而不是由应用层静默截断。 - 只有在 Cluster 场景下再比较
SHARD_K_RATIO,同时记录召回变化和延迟。
常见误区是把“标签过滤”和“向量排序”拆成两次查询:这样应用层可能先拿到过大的候选集,再承担过滤、排序和分页成本。把范围、距离和返回字段都写进 FT.SEARCH,查询意图更明确,也更容易排查参数错误。
常见问题
KNN 为什么必须写 DIALECT 2?
Redis 官方向量查询示例使用查询方言 2;组合 KNN、参数绑定和后续向量表达式时,应显式写出,避免环境默认值不同。
距离越小一定越相似吗?
只能在同一向量模型和同一距离度量下比较。本文按距离升序示例,实际含义仍取决于索引的 DISTANCE_METRIC 和模型输出。
为什么过滤条件写了却混入其他标签?
先检查字段是否按 TAG 建索引、标签值是否包含分隔符,再确认过滤表达式和向量查询位于同一条 FT.SEARCH 语句中。
-
113 收藏
-
451 收藏
-
343 收藏
-
468 收藏
-
461 收藏
-
320 收藏
-
154 收藏
-
462 收藏
-
484 收藏
-
410 收藏
-
397 收藏
-
178 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习