登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis Vector Set 怎么按相似度过滤结果

来源:17golang原创

时间:2026-10-06 00:12:48 433浏览 收藏

Redis Vector Set 要按相似度过滤结果,直接在 VSIM 中使用 EPSILON。它接收的不是“最低相似度”,而是最大距离:如果业务要求相似度至少为 0.85,应设置 EPSILON 0.15。换算公式是 EPSILON = 1 - 最低相似度。

参数速记
  • EPSILON:按相似度门槛过滤,值越小,要求越严格。
  • COUNT:只限制最多返回多少条,不保证这些结果足够相似。
  • WITHSCORES:把分数返回给客户端,便于观察和调参,本身不做过滤。
  • FILTER:过滤 JSON 属性,不是过滤相似度分数。

官方文档:https://redis.io/docs/latest/commands/vsim/

前置条件:先确认是 Vector Set 的阈值问题

VSIM 属于 Redis Vector Set 命令,官方命令页标注其从 Redis Open Source 8.0.0 起可用。本文只讨论 Vector Set 中的相似度门槛;如果你使用的是 Redis Search 的向量索引,查询语法和距离字段并不是同一套接口。

Vector Set 的分数范围是 1 到 0:1 表示向量相同,0 表示方向相反。EPSILON 的范围同样是 0 到 1,但含义是“允许离查询向量多远”。因此两者方向相反。

最低相似度对应 EPSILON筛选含义
0.950.05只保留非常接近的候选
0.850.15保留相似度不低于 0.85 的候选
0.700.30放宽召回范围,结果通常更多

第一步:初始化一个最小 Vector Set

下面用三维向量创建实验集合。VALUES 3 中的 3 是维度,后面必须紧跟三个浮点值和元素名。所有元素维度要保持一致:

# 写入四个三维向量,首次 VADD 会创建 Vector Set
VADD demo:articles VALUES 3 1.00 0.00 0.00 article:redis
VADD demo:articles VALUES 3 0.96 0.18 0.00 article:cache
VADD demo:articles VALUES 3 0.72 0.69 0.00 article:database
VADD demo:articles VALUES 3 -1.00 0.00 0.00 article:travel

# 检查元素数量和向量维度,排除初始化错误
VCARD demo:articles
VDIM demo:articles

预期结构是 VCARD 返回 4,VDIM 返回 3。如果维度不一致,先修正写入数据,不要用搜索参数掩盖输入问题。

第二步:先用 WITHSCORES 观察分数

阈值不应凭感觉直接写死。先使用较大的 COUNT 返回一批候选,再通过 WITHSCORES 观察业务中的正例、边界例和负例大致落在哪个区间:

# 以外部查询向量搜索,返回最多 10 条并附带相似度分数
VSIM demo:articles VALUES 3 1.00 0.00 0.00 WITHSCORES COUNT 10

RESP2 返回时,元素名与分数通常交替出现;RESP3 可以返回成员到分数的映射。不要把数组位置写死成唯一协议,客户端解析时应按所用 RESP 版本处理。

WITHSCORES 的作用只是让分数可见。若只写 COUNT 10,Redis 会尽量返回最相似的十条,但第十条可能远低于业务可接受的门槛;这就是需要 EPSILON 的原因。

第三步:用 EPSILON 设定相似度门槛

假设实验观察后决定“相似度至少 0.85”,先换算为距离上限 1 - 0.85 = 0.15,再把它写进同一个 VSIM:

# EPSILON 0.15 等价于只保留相似度不低于 0.85 的候选
VSIM demo:articles VALUES 3 1.00 0.00 0.00 \
  WITHSCORES COUNT 10 EPSILON 0.15

这里的 COUNT 10 仍是结果数量上限,而 EPSILON 0.15 才是质量下限。满足门槛的元素只有三条时,命令可以少于十条;没有元素达到门槛时,结果可以为空。这比先取固定十条再在客户端按分数删除更直接,也减少了无用结果传输。

Redis VSIM 查询向量、候选相似度、EPSILON 距离上限与接受拒绝集合关系图
图1:VSIM 的 EPSILON 表示距离上限,最低相似度与它满足 1 减关系的静态说明图,不是运行截图。

如果查询基准已经是集合中的元素,可以把 VALUES 改成 ELE:

# 以集合内已有元素为查询基准,仍使用同一距离门槛
VSIM demo:articles ELE article:redis \
  WITHSCORES COUNT 10 EPSILON 0.15

使用 ELE 时,查询元素自身可能以接近 1 的分数出现在结果里。如果业务不想返回自身,应在应用层按元素名排除;不要为了排除自身而错误地收紧相似度阈值。

第四步:区分 EPSILON、COUNT 和 FILTER

名称相近的“过滤”其实作用在不同层。EPSILON 处理向量距离,FILTER 处理元素 JSON 属性,COUNT 处理返回数量。三者可以组合,但不能互相替代。

按属性过滤不是按分数过滤

先用 VSETATTR 给元素关联 JSON 属性,再把属性表达式放进 FILTER。例如只检索已发布的中文内容:

# 为候选元素写入 JSON 属性,供 FILTER 使用
VSETATTR demo:articles article:redis '{"lang":"zh","published":true}'
VSETATTR demo:articles article:cache '{"lang":"zh","published":true}'
VSETATTR demo:articles article:database '{"lang":"en","published":true}'
VSETATTR demo:articles article:travel '{"lang":"zh","published":false}'

# 同时应用相似度门槛、属性条件和返回数量上限
VSIM demo:articles VALUES 3 1.00 0.00 0.00 \
  WITHSCORES COUNT 10 EPSILON 0.15 \
  FILTER '.lang == "zh" and .published == true'

这条命令先定义“够不够相似”和“属性是否匹配”两个独立条件。FILTER-EF 控制属性过滤最多尝试多少次,也不是相似度阈值。

Redis VSIM 与 EPSILON、COUNT、WITHSCORES、FILTER、EF、TRUTH、结果集的职责边界结构图
图2:EPSILON、COUNT、FILTER、EF 和 TRUTH 各自作用于不同查询边界的静态结构图,不是运行截图。

第五步:检查近似搜索边界

VSIM 默认可以执行近似搜索。EPSILON 只规定“返回结果必须满足什么距离门槛”,并不保证近似搜索一定找全所有满足门槛的元素。若发现已知正例偶尔没有被召回,应先把阈值和召回问题分开处理:

  • 门槛太严格:适当增大 EPSILON,相当于降低最低相似度。
  • 召回不足:增大 EF,让搜索探索更多节点,但延迟和计算量会增加。
  • 需要基准:临时用 TRUTH 做精确线性扫描,对比近似结果;它是 O(N) 且明显更慢,不适合作为默认线上方案。
# 提高探索量,阈值仍保持相似度至少 0.85
VSIM demo:articles VALUES 3 1.00 0.00 0.00 \
  WITHSCORES COUNT 10 EPSILON 0.15 EF 200

# 仅用于小规模基准对照,TRUTH 会执行精确线性扫描
VSIM demo:articles VALUES 3 1.00 0.00 0.00 \
  WITHSCORES COUNT 10 EPSILON 0.15 TRUTH

调参时应固定查询集,分别记录满足业务定义的正例是否被召回、返回数量和延迟。不要只看单次分数排序,也不要把提高 EF 误认为提高相似度门槛。

扩展实验:把业务阈值写成可检查规则

实际项目可以先建立三组查询样本:必须命中的正例、刚好可接受的边界例、必须排除的负例。选择阈值时,让边界例尽量稳定地位于门槛内,同时让负例位于门槛外。若不同业务场景的分数分布差异明显,应使用不同阈值,不要让一个全局 EPSILON 服务所有检索意图。

目标使用选项判断标准
只保留足够相似的结果EPSILONscore >= 1 - epsilon
控制最多返回多少条COUNT结果条数不超过上限
查看分数并调阈值WITHSCORES客户端能读取成员与分数
限定语言、状态、年份FILTER元素 JSON 属性符合表达式
改善近似搜索召回EF已知正例召回更稳定,成本可接受
建立精确结果基准TRUTH与近似结果对照,不作为默认线上查询

清理实验数据

确认命令和阈值后,删除本次实验键,避免它与正式集合混在一起:

# 删除本文实验使用的 Vector Set 键
DEL demo:articles

相关问题

为什么相似度 0.8 要写 EPSILON 0.2

因为 EPSILON 表示距离上限,而 Vector Set 的相似度与这里的距离满足 similarity = 1 - distance。相似度至少 0.8,等价于距离小于等于 0.2。

只用 COUNT 能过滤低分结果吗

不能。COUNT 只保留最靠前的若干候选;如果整个集合都不够相似,它仍可能返回低分结果。质量门槛要用 EPSILON。

FILTER 能直接写相似度条件吗

不能把它当分数表达式使用。FILTER 面向 VSETATTR 保存的 JSON 属性;相似度门槛由 EPSILON 负责。

加了 EPSILON 为什么已知相似元素仍没返回

先确认换算方向和向量维度,再区分门槛与近似召回。阈值正确但召回不足时,可以提高 EF,并用小规模 TRUTH 结果建立对照。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>