Drizzle | 使用 pgvector 扩展进行向量相似度搜索
本指南假定您熟悉
- 开始使用 PostgreSQL
- Select 语句
- 索引
- sql 运算符
- pgvector 扩展
- Drizzle kit
- 您应该已经安装了
openai
包 来生成嵌入。
npm
yarn
pnpm
bun
npm i openai
- 您应该使用
[email protected]
和[email protected]
或更高版本。
要在 PostgreSQL 中使用 Drizzle ORM 实现向量相似度搜索,您可以使用 pgvector
扩展。此扩展提供了一组函数来处理向量并执行相似度搜索。
目前,Drizzle 不会自动创建扩展,因此您需要手动创建它。创建一个空的迁移文件并添加 SQL 查询。
npx drizzle-kit generate --custom
CREATE EXTENSION vector;
要执行相似度搜索,您需要创建一个包含向量列的表,并在该列上创建 HNSW
或 IVFFlat
索引以获得更好的性能。
schema.ts
migration.sql
import { index, pgTable, serial, text, vector } from 'drizzle-orm/pg-core';
export const guides = pgTable(
'guides',
{
id: serial('id').primaryKey(),
title: text('title').notNull(),
description: text('description').notNull(),
url: text('url').notNull(),
embedding: vector('embedding', { dimensions: 1536 }),
},
(table) => [
index('embeddingIndex').using('hnsw', table.embedding.op('vector_cosine_ops')),
]
);
embedding
列用于存储指南描述的向量嵌入。向量嵌入只是某些数据的表示。它将不同类型的数据转换为语言模型可以处理的通用格式(向量)。这使我们能够执行数学运算,例如测量两个向量之间的距离,以确定两个数据项的相似或不同程度。
在此示例中,我们将使用 OpenAI
模型为描述生成嵌入。
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env['OPENAI_API_KEY'],
});
export const generateEmbedding = async (value: string): Promise<number[]> => {
const input = value.replaceAll('\n', ' ');
const { data } = await openai.embeddings.create({
model: 'text-embedding-ada-002',
input,
});
return data[0].embedding;
};
要通过嵌入搜索相似的指南,您可以使用 gt
和 sql
运算符以及 cosineDistance
函数来计算 embedding
列与生成的嵌入之间的相似度。
import { cosineDistance, desc, gt, sql } from 'drizzle-orm';
import { generateEmbedding } from './embedding';
import { guides } from './schema';
const db = drizzle(...);
const findSimilarGuides = async (description: string) => {
const embedding = await generateEmbedding(description);
const similarity = sql<number>`1 - (${cosineDistance(guides.embedding, embedding)})`;
const similarGuides = await db
.select({ name: guides.title, url: guides.url, similarity })
.from(guides)
.where(gt(similarity, 0.5))
.orderBy((t) => desc(t.similarity))
.limit(4);
return similarGuides;
};
const description = 'Guides on using Drizzle ORM with different platforms';
const similarGuides = await findSimilarGuides(description);
[
{
name: 'Drizzle with Turso',
url: '/docs/tutorials/drizzle-with-turso',
similarity: 0.8642314333984994
},
{
name: 'Drizzle with Supabase Database',
url: '/docs/tutorials/drizzle-with-supabase',
similarity: 0.8593631126014918
},
{
name: 'Drizzle with Neon Postgres',
url: '/docs/tutorials/drizzle-with-neon',
similarity: 0.8541051184461372
},
{
name: 'Drizzle with Vercel Edge Functions',
url: '/docs/tutorials/drizzle-with-vercel-edge-functions',
similarity: 0.8481551084241092
}
]