多租户知识库共用一个 collection,代码先 search 取前 20 再按 tenant_id 过滤,一次测试里 20 条全属于别的租户,返回空结果,用户看到未找到相关内容。
这类报错背后常见的原因有几处,逐个排除就行。先检索后过滤,候选窗口被其它租户的数据占满;过滤字段没建索引,事后过滤本身也很慢;租户字段用了字符串比较,大小写不一致筛掉正确的;默认查询没带租户条件,指望上层补偿。
上来先把租户条件写进检索请求而不是事后过滤
curl -X POST http://127.0.0.1:6333/collections/kb/points/search -H "Content-Type: application/json" -d '{"vector":[0.1,0.2],"limit":5,"filter":{"must":[{"key":"tenant_id","match":{"value":"t42"}}]}}'
给租户字段建等值索引
curl -X PUT http://127.0.0.1:6333/collections/kb/index -H "Content-Type: application/json" -d '{"field_name":"tenant_id","field_schema":"keyword"}'
随后验证该租户下的点数
curl -X POST http://127.0.0.1:6333/collections/kb/points/count -H "Content-Type: application/json" -d '{"filter":{"must":[{"key":"tenant_id","match":{"value":"t42"}}]},"exact":true}'
等前面都确认过,再用另一个租户做交叉验证
curl -X POST http://127.0.0.1:6333/collections/kb/points/scroll -H "Content-Type: application/json" -d '{"filter":{"must":[{"key":"tenant_id","match":{"value":"t43"}}]},"limit":3,"with_payload":true}'
改完先别撤,确认这几项。每次检索返回的条数与租户实际文档数匹配,跨租户查询返回空,日志里 filter 始终带上 tenant_id。
补一句。租户隔离放在检索前是硬约束,事后过滤不只是浪费候选,高峰期还会把结果直接清空。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
