Go の Bun ORM + pgvector をスキーマ自動生成と共存させる方法
Go
PostgreSQL
pgvector
Bun ORM のモデル定義から DDL を自動生成する構成に pgvector のベクトルカラムを組み込む場合、pgvector-go パッケージの pgvector.Vector 型をフィールドに使い、bun:"type:vector(768)" のように型タグで次元を明示する。これで CreateTable の DDL 生成、INSERT 時のベクトルリテラル化([0.1,0.2,...] 形式)、SELECT の scan がすべて素通りする。[]float32 を直接フィールドにすると Postgres 配列形式({...})で書き込まれて vector 型と互換がないため通らない。
落とし穴:
- belongs-to リレーションを定義しても CreateTable の FK 自動生成が効かないケースがある。FK が必要なら明示的に DDL を出力する(深追いするより明示定義が確実)。
- カラムの次元数と embedding API の出力次元は必ず一致させる。API 側のレスポンス次元をサービス層で検証してから保存すると、モデル変更時の混入を防げる。
- 類似検索はコサイン距離演算子
<=>を使えばベクトルの正規化は不要(距離計算自体が正規化を含む)。1 - 距離を類似度スコアとして返すと扱いやすい。
インデックスの判断基準: 数千件規模までは索引なしの全件スキャンで十分速い(1 ベクトル 768 次元 ≒ 3KB)。件数が増えて遅くなってから HNSW インデックスを後付けすればよく、最初から張る必要はない。pgvector のインデックスは 2000 次元が上限のため、高次元モデルを使う場合は出力次元の縮小(例: 768)を先に決めておく。