前置与后置过滤
向量检索带条件过滤(租户、标签、生效时间)时有两条路:前置过滤只在满足条件的向量里搜索,结果准确但过滤集稀疏时会变慢;后置过滤先检索再筛选,速度快但 top-k 可能被筛空,需要靠超采样或多取候选来弥补。选择取决于过滤条件的命中比例。
基本信息
| 过滤对象 | 向量库中的标量字段:租户、部门、密级、类型、生效日期 |
|---|---|
| 前置过滤 | 条件先收窄候选集,再做距离计算 |
| 后置过滤 | 先算距离取 top-k,再按条件筛掉不符合的 |
| 前提 | 过滤字段必须建标量索引,否则延迟随数据量恶化 |
两种过滤方式
| 方式 | 执行顺序 | 典型风险 |
|---|---|---|
| 前置过滤(pre) | 先筛条件再算距离 | 过滤集稀疏时召回下降、延迟上升 |
| 后置过滤(post) | 先算距离再筛条件 | 过滤条件强时 top-k 结果不足 |
后置过滤的超采样补偿
后置过滤的超采样补偿
hits = vector_store.search(q_vec, top_k=k * 5)
kept = [h for h in hits if h.payload.get("tenant") == tenant_id]
kept = kept[:k] # 过滤后截断
assert len(kept) == k or kept, "命中不足时降级为仅过滤检索"使用要点
- 先估算命中比例:条件越严,越应该用前置过滤或提高超采样倍数
- 过滤字段建索引:不建索引时条件过滤会退化为全表扫描
- 按最差分布压测:小租户或冷门标签才真正暴露问题
- 返回条数不足要显式监测:静默返回少量结果会让答案缺要点却无异常
- 过滤条件与权限解耦:权限字段由服务端强制拼接,不接受客户端传入
按场景选择
| 场景 | 推荐 | 原因 |
|---|---|---|
| 多租户隔离 | 前置过滤 | 条件长期稳定、必须严格隔离 |
| 按时间范围过滤 | 前置过滤 | 范围条件收窄明显,命中比例可判断 |
| 可选标签加权 | 后置过滤 + 超采样 | 保留相关度排序的灵活性 |
| 小比例冷门条件 | 前置过滤 | 后置过滤几乎必然取不满条数 |
主流向量库对带过滤检索都有专门实现与参数;上线前用最差分布(最小的租户)压测,而不是用平均情况评估。