首页
/ Prisma Next 如何用 pgvector 扩展声明向量列并执行余弦相似度查询?

Prisma Next 如何用 pgvector 扩展声明向量列并执行余弦相似度查询?

2026-09-08 19:39:35作者:仰钰奇

如果你已经在用 Prisma Next 管理 PostgreSQL 数据库,现在需要给表加一个向量列来存 embedding,并支持“按余弦相似度找最相似的 N 条记录”这类查询,pgvector 扩展包就是官方提供的路径。@prisma/orm-extension-pgvector 为 PostgreSQL 增加 vector 数据类型的支持以及向量相似度操作(如余弦距离),并在扩展被组成进应用时自动安装数据库端的 pgvector 扩展。当前公开包版本为 8.0.0-rc.8(见 公开发布包 package.json),本文所有步骤都围绕“声明向量列 → 安装服务端扩展 → 执行余弦相似度查询”这一条路径展开。

准备条件与安装

  • 数据库是 PostgreSQL,且允许执行 CREATE EXTENSION 安装 pgvector 服务端扩展;
  • 项目通过 Prisma Next 的 extensions 机制组成扩展包。

安装公开包:

pnpm add @prisma/orm-extension-pgvector

这个包的入口点见 公开发布包 README

入口点 用途
/pack 组成进 extensions: [...] 的扩展 pack,纯数据、无运行时导入
/column-types 向量列 author(维度化 vector 列)
/codec-types/operation-types 生成的 contract 引用的类型
/runtime 注册 codec 和向量操作的运行时扩展
/control 控制端描述符与安装服务端扩展的 baseline migration

注意区分:仓库内部扩展包文档(packages/3-extensions/pgvector/README.md)中的示例代码使用 @internal/... 包名;公开发布包 @prisma/orm-extension-pgvector 提供同名入口点,下文的 TS 契约示例即引自该内部 README,包名对应关系以此为准。

把扩展组成进 prisma.config.ts

prisma.config.ts 中导入 /control 入口并加入 extensions 数组。仓库示例应用 prisma-8-demo 的配置 是真实可运行的参考(示例中还组成了另一个 engagementStatsControl 扩展,与向量无关,可省略):

import 'dotenv/config';
import { defineConfig } from '@prisma/cli-engine';
import pgvector from '@prisma/orm-extension-pgvector/control';
import { defineConfig as ormConfig } from '@prisma/orm-postgres/config';

export default defineConfig({
  orm: ormConfig({
    contract: './src/prisma/contract.prisma',
    extensions: [pgvector],
    db: {
      // biome-ignore lint/style/noNonNullAssertion: loaded from .env
      connection: process.env['DATABASE_URL']!,
    },
  }),
});

contract 指向你的契约文件,路径按你的项目调整;DATABASE_URL 需通过环境变量提供。

声明向量列

内部扩展包 README 给出的 TS 契约写法是:通过 pack ref 启用 pgvector 命名空间,并用带维度的 vector(N) 工厂声明列:

import { int4Column, textColumn } from '@internal/adapter-postgres/column-types';
import sqlFamily from '@internal/family-sql/pack';
import { defineContract, field, model } from '@internal/sql-contract-ts/contract-builder';
import { vector } from '@internal/extension-pgvector/column-types';
import pgvector from '@internal/extension-pgvector/pack';
import postgres from '@internal/target-postgres/pack';

export const contract = defineContract({
  family: sqlFamily,
  target: postgres,
  extensions: { pgvector },
  models: {
    Post: model('Post', {
      fields: {
        id: field.column(int4Column).id(),
        title: field.column(textColumn),
        // Dimensioned vector — `field.embedding` resolves to `Vector<1536>`.
        embedding: field.column(vector(1536)).optional(),
      },
    }).sql({ table: 'post' }),
  },
});

关于 vector(N) 工厂,文档明确的两点:

  • 每个 pgvector 列必须通过 vector(N) 声明显式维度——paramsSchema 在契约边界校验维度,renderOutputType 据此生成 contract.d.ts 中的列类型;
  • field.embedding 因此解析为 Vector<1536>,这是一个带维度的 branded number[] 类型;运行时代码侧类型则是 CodecTypes['pg/vector@1']['output'] = number[]

如果沿用示例应用的 PSL 契约,向量列在 contract.prisma 中声明为 embedding Embedding1536?(可空),扩展仍然通过上面 prisma.config.tsextensions 组成。

应用 baseline migration 安装服务端扩展

这一步是必做项。pgvector 包在契约空间内携带一个 on-disk baseline migration,执行内容为 CREATE EXTENSION IF NOT EXISTS vector。只要扩展已经通过 extensions 组成进应用,prisma db initprisma db update 会自动应用该 baseline(以及后续迁移);如果手动建库,等价的 DDL 是:

CREATE EXTENSION IF NOT EXISTS vector;

文档强调:在运行任何使用向量列的查询之前,先确认 baseline migration(或等价 DDL)已经应用。

执行余弦相似度查询

扩展注册了 cosineDistancecosineSimilarity 两个操作,对应能力键 pgvector.cosine

  • cosineDistance:余弦距离,SQL 上使用 pgvector 的 <=> 操作符(vector1 <=> vector2),签名 cosineDistance(rhs: number[] | vector): number
  • cosineSimilarity:余弦相似度,定义为 1 - (vector1 <=> vector2)

示例应用提供两条查询路径,都来自可运行的代码。

主路径:SQL 查询通道similarity-search.ts 对一个查询向量检索最相似的 N 篇文章:

import { db } from '../prisma/db';

/**
 * Search for posts by cosine distance to a query vector.
 * Returns the top N posts ordered by similarity (closest first).
 */
export async function similaritySearch(queryVector: number[], limit = 10) {
  const plan = db.sql.public.post
    .select('id', 'title')
    .select('distance', (f, fns) => fns.cosineDistance(f.embedding, queryVector))
    .orderBy((f, fns) => fns.cosineDistance(f.embedding, queryVector), { direction: 'asc' })
    .limit(limit)
    .build();
  return db.runtime().query(plan);
}

db 是示例应用生成后的客户端入口(src/prisma/db.ts),queryVector 是你自己的查询向量(number[]),limit 控制返回条数。距离通过 select('distance', ...) 作为结果列带出,并按距离升序排序。pack README 中还给出了参数化写法:cosineDistance(param('queryVector')) 配合 .build({ params: { queryVector } }),适合把查询向量绑定为 SQL 参数的场景。

可选路径:ORM 客户端通道find-similar-posts.ts 演示了以“已有文章的 embedding 作为查询向量”找相似文章:先按 id 取出目标文章的 embedding,再以列上的 .cosineDistance(embedding) 作为谓词和排序键。示例中的过滤条件 .where((p) => cosineDistanceFrom(p).lt(1)) 是该演示代码使用的示例阈值,不是扩展的固定判定标准,实际取值应结合你的数据自行决定:

const cosineDistanceFrom = (fromPost: ModelAccessor<Contract, 'Post'>) =>
  fromPost.embedding.cosineDistance(embedding);

return db.Post.where((p) => p.id.neq(typedPostId))
  .where((p) => cosineDistanceFrom(p).lt(1))
  .orderBy((p) => cosineDistanceFrom(p).asc())
  .select('id', 'title', 'userId')
  .limit(limit)
  .all();

验证结果

  1. 类型层面:emit 后的 contract 类型文件中出现维度化向量类型。示例应用生成的 contract.d.ts 中即为 readonly embedding: Vector<1536> | null;,说明 vector(1536) 的维度元数据已进入生成的类型。
  2. 查询层面:运行 similaritySearch 得到按距离升序排列的 top N 行(文档注释即“closest first”);若走 ORM 通道,all() 返回按余弦距离升序的相似文章列表。两个示例函数都没有固定输出值,判断依据是结果包含 distance/排序语义且条数不超过 limit

限制与边界

  • 该 pack 面向 PostgreSQL:为“已安装 pgvector 扩展的 PostgreSQL 数据库”提供 vector 类型与相似度操作,不适用于其他数据库目标;
  • 未带维度的向量列不被支持——vector(N) 的显式维度是描述符签名的前提;
  • 向量查询依赖服务端扩展:baseline migration(或 CREATE EXTENSION IF NOT EXISTS vector)未应用前,向量列的负载无法运行;
  • 公开包处于 8.0.0-rc.x 预发布版本线,API 面以对应版本的文档和示例为准。

延伸阅读:扩展包命名与布局见 Extension-Packs-Naming-and-Layout.md,参数化类型的高阶 codec 模型见 ADR 208,示例应用的完整用法见 examples/prisma-8-demo

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391