现场是这样的。用 chromadb 0.5.3 的 PersistentClient 做批量去重,把 3000 个 doc_id 塞进 where={“doc_id”:{“$in”: ids}},query 直接抛 ValueError,提示过滤取值数量超限,改成逐个查又慢到不可用。
中间走过弯路,把「0.5 版本收紧了过滤实现,0.4 里能过的写法现在不行」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。Chroma 的 where 过滤器对 $in 列表长度有内部上限;底层 SQLite 单条语句的变量个数受限,超了编译就失败;这批 id 本来就是主键,其实不需要走 where 过滤。
动手时先确认限制来自版本而不是数据
python -c "import chromadb;print(chromadb.__version__)"
再往下把长列表按 500 一段切开分别处理
python -c "ids=[f'd{i}' for i in range(3000)];print([len(ids[i:i+500]) for i in range(0,len(ids),500)])"
能按主键取就别用 where,直接批量 get
python -c "import chromadb;c=chromadb.PersistentClient(path='./db').get_collection('kb');print(len(c.get(ids=[f'd{i}' for i in range(50)])['ids']))"
升级到修过该限制的小版本再跑一遍
pip install -U "chromadb>=0.5.5"
当时还开着另一个排查窗口,两边日志对照着看才定位到。
别只看报错消失,验证要多做一步。3000 个 id 全部命中,返回条数与输入一致,不再出现过滤取值超限的 ValueError。
容易忽略的是,get(ids=) 只按主键取,拿不到相似度;要排序还得切片 query 再自己合并结果。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
