gRPC端口必须填6334,填6333会因协议错配导致“frame too large”错误;CreateCollection需显式指定VectorsConfig维度;Search过滤须用qdrant.Filter结构体而非map;Upsert推荐用于批量写入,单次100–500条为宜。

gRPC端口填6333会报"frame too large"错误
Qdrant 的 HTTP 和 gRPC 是两个完全独立的服务端口,不能混用。Go 客户端默认走 gRPC 协议,必须用 6334;若误填 6333(HTTP 端口),gRPC 库会尝试解析 HTTP 响应为二进制帧,直接触发 "frame too large" 或 "unknown server compatibility" 类错误。
-
6333:仅限 curl / REST API / Dashboard 访问,Go 客户端连不上 -
6334:gRPC 专用端口,客户端初始化时必须指定 - 启动容器时务必暴露两个端口:
-p 6333:6333 -p 6334:6334 - 如遇版本兼容警告,可临时加配置
SkipCompatibilityCheck: true,但生产环境建议客户端与 Qdrant 版本对齐(如都用 v1.10.x)
CreateCollection必须显式指定VectorsConfig维度
Qdrant 不允许“动态推断”向量维度,创建集合时若漏传或传错 VectorsConfig,后续所有 Upsert 都会失败,错误提示模糊(常为 invalid vector dimension 或空 panic)。
- 维度值必须和你实际插入的向量长度严格一致,比如 OpenAI
text-embedding-3-small输出是 1536 维,就得写qdrant.NewVectorsConfig(1536) - 不支持多向量字段自动识别,如有多个向量字段,需用
VectorStruct显式定义 - 集合创建后无法修改维度,删库重建是唯一办法
Search查询时过滤 payload 要用Filter结构体,不是 map
很多开发者习惯把过滤条件写成 map[string]interface{} 传进去,结果查不到数据也不报错——因为 Qdrant Go 客户端的 SearchPoints.Filter 字段类型是 *qdrant.Filter,底层是 Protocol Buffer 结构,不能直传原始 map。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 正确做法是用
qdrant.NewFilter()+qdrant.NewMatchValue()等构造器链式构建 - 例如查
category == "product":Filter: qdrant.NewFilter().WithMust(qdrant.NewMatchString("category", "product")) - 全文检索需额外启用
with_payload并确保字段已建索引,否则filter对 text 字段无效 - 过滤性能高度依赖 payload 索引,未索引字段会导致全量扫描
批量写入用Upsert而非Insert,并注意points大小限制
Upsert 是推荐的写入方式,它能自动去重(按 id)、支持部分更新;而 Insert 已被标记为 deprecated。但一次提交的 points 数量过大(如超 1000 条)容易触发 gRPC 流控或 OOM,尤其在低内存容器中。
立即学习“go语言免费学习笔记(深入)”;
- 单次
Upsert建议控制在 100–500 条,具体看向量维数和 payload 大小 - 每条
PointStruct的Vector必须是[]float64,不能是[]float32(客户端会 panic) - 如果需要高吞吐写入,应开启 Qdrant 的
optimizers配置(如max_segment_size),否则小批量写入反而更慢 - 没有事务语义,部分失败时需自己捕获
err并重试失败点

















