查询向量
Perform similarity search and retrieve vectors using JavaScript SDK or Postgres.
此功能处于测试阶段
预计会有快速变化、功能有限,并可能出现破坏性更新。随着我们改进体验并扩大访问,欢迎分享反馈。
🌐 Expect rapid changes, limited features, and possible breaking updates. Share feedback as we refine the experience and expand access.
向量相似度搜索使用距离度量找到与查询向量最相似的向量。你可以用 JavaScript SDK 查询向量,也可以直接用 SQL 从 Postgres 查询。
🌐 Vector similarity search finds vectors most similar to a query vector using distance metrics. You can query vectors using the JavaScript SDK or directly from Postgres using SQL.
与 pgvector 的比较
向量桶和它们使用的任何 外部数据封装器 (FDW) 只支持一种相似性搜索算法,即 <===> 距离运算符。
🌐 Vector buckets and any Foreign Data Wrappers (FDW) they use only support one similarity search algorithm, the <===> distance operator.
基础相似性搜索 #
🌐 Basic similarity search
1import { createClient } from '@supabase/supabase-js'23const supabase = createClient('https://your-project-id.supabase.co', 'your-service-key')45const index = supabase.storage.vectors.from('embeddings').index('documents-openai')67// Query with a vector embedding8const { data, error } = await index.queryVectors({9 queryVector: {10 float32: [0.1, 0.2, 0.3 /* ... embedding of 1536 dimensions ... */],11 },12 topK: 5,13 returnDistance: true,14 returnMetadata: true,15})1617if (error) {18 console.error('Query failed:', error)19} else {20 // Results are ranked by similarity (lowest distance = most similar)21 data.vectors.forEach((result, rank) => {22 console.log(`${rank + 1}. ${result.metadata?.title}`)23 console.log(` Similarity score: ${result.distance.toFixed(4)}`)24 })25}语义搜索 #
🌐 Semantic search
通过将查询文本嵌入来查找与查询相似的文档:
🌐 Find documents similar to a query by embedding the query text:
1import { createClient } from '@supabase/supabase-js'2import OpenAI from 'openai'34const supabase = createClient(...)5const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })67async function semanticSearch(query, topK = 5) {8 // Embed the query9 const queryEmbedding = await openai.embeddings.create({10 model: 'text-embedding-3-small',11 input: query12 })1314 const queryVector = queryEmbedding.data[0].embedding1516 // Search for similar vectors17 const { data, error } = await supabase.storage.vectors18 .from('embeddings')19 .index('documents-openai')20 .queryVectors({21 queryVector: { float32: queryVector },22 topK,23 returnDistance: true,24 returnMetadata: true25 })2627 if (error) {28 throw error29 }3031 return data.vectors.map((result) => ({32 id: result.key,33 title: result.metadata?.title,34 similarity: 1 - result.distance, // Convert distance to similarity (0-1)35 metadata: result.metadata36 }))37}3839// Usage40const results = await semanticSearch('How do I use vector search?')41results.forEach((result) => {42 console.log(`${result.title} (${(result.similarity * 100).toFixed(1)}% similar)`)43})筛选相似搜索 #
🌐 Filtered similarity search
1const index = supabase.storage.vectors2 .from('embeddings')3 .index('documents-openai')45// Search with metadata filter6const { data } = await index.queryVectors({7 queryVector: { float32: [...embedding...] },8 topK: 10,9 filter: {10 // Filter by metadata fields11 category: 'electronics',12 in_stock: true,13 price: { $lte: 500 } // Less than or equal to 50014 },15 returnDistance: true,16 returnMetadata: true17})获取特定向量 #
🌐 Retrieving specific vectors
1const index = supabase.storage.vectors.from('embeddings').index('documents-openai')23const { data, error } = await index.getVectors({4 keys: ['doc-1', 'doc-2', 'doc-3'],5 returnData: true,6 returnMetadata: true,7})89if (!error) {10 data.vectors.forEach((vector) => {11 console.log(`${vector.key}: ${vector.metadata?.title}`)12 })13}列出向量 #
🌐 Listing vectors
1const index = supabase.storage.vectors.from('embeddings').index('documents-openai')23let nextToken = undefined4let pageCount = 056do {7 const { data, error } = await index.listVectors({8 maxResults: 100,9 nextToken,10 returnData: false, // Don't return embeddings for faster response11 returnMetadata: true,12 })1314 if (error) break1516 pageCount++17 console.log(`Page ${pageCount}: ${data.vectors.length} vectors`)1819 data.vectors.forEach((vector) => {20 console.log(` - ${vector.key}: ${vector.metadata?.title}`)21 })2223 nextToken = data.nextToken24} while (nextToken)混合搜索:向量 + 关系数据 #
🌐 Hybrid search: Vectors + relational data
将相似性搜索与 SQL 过滤和连接结合起来:
🌐 Combine similarity search with SQL filtering and joins:
1async function hybridSearch(queryVector, filters) {2 const index = supabase.storage.vectors.from('embeddings').index('documents-openai')34 // Get similar vectors with filters5 const { data: vectorResults } = await index.queryVectors({6 queryVector: { float32: queryVector },7 topK: 100,8 filter: filters,9 returnDistance: true,10 returnMetadata: true,11 })1213 // Get additional details from relational database14 const { data: details } = await supabase15 .from('documents')16 .select('*')17 .in(18 'id',19 vectorResults.vectors.map((v) => v.metadata?.doc_id)20 )2122 // Merge results23 return vectorResults.vectors.map((vector) => {24 const detail = details?.find((d) => d.id === vector.metadata?.doc_id)25 return {26 ...vector,27 ...detail,28 }29 })30}真实案例 #
🌐 Real-world examples
RAG(检索增强生成) #
🌐 RAG (retrieval-augmented generation)
1import OpenAI from 'openai'2import { createClient } from '@supabase/supabase-js'34async function retrieveContextForLLM(userQuery) {5 const supabase = createClient(...)6 const openai = new OpenAI()78 // 1. Embed the user query9 const queryEmbedding = await openai.embeddings.create({10 model: 'text-embedding-3-small',11 input: userQuery12 })1314 // 2. Retrieve relevant documents15 const { data: vectorResults } = await supabase.storage.vectors16 .from('embeddings')17 .index('documents-openai')18 .queryVectors({19 queryVector: { float32: queryEmbedding.data[0].embedding },20 topK: 5,21 returnMetadata: true22 })2324 // 3. Use vectors to augment LLM prompt25 const context = vectorResults.vectors26 .map(v => v.metadata?.content || '')27 .join('\n\n')2829 const response = await openai.chat.completions.create({30 model: 'gpt-4',31 messages: [32 {33 role: 'system',34 content: `Use the following context to answer the user's question:\n\n${context}`35 },36 {37 role: 'user',38 content: userQuery39 }40 ]41 })4243 return response.choices[0].message.content44}产品推荐 #
🌐 Product recommendations
1async function recommendProducts(userEmbedding, topK = 5) {2 const supabase = createClient(...)34 // Find similar products5 const { data } = await supabase.storage.vectors6 .from('embeddings')7 .index('products-openai')8 .queryVectors({9 queryVector: { float32: userEmbedding },10 topK,11 filter: {12 in_stock: true13 },14 returnMetadata: true15 })1617 return data.vectors.map((result) => ({18 id: result.metadata?.product_id,19 name: result.metadata?.name,20 price: result.metadata?.price,21 similarity: 1 - result.distance22 }))23}在相似性搜索前进行过滤 #
🌐 Filtering before similarity search
1// Use metadata filters to reduce search scope2const { data } = await index.queryVectors({3 queryVector,4 topK: 100,5 filter: {6 category: 'electronics', // Pre-filter by category7 },8})下一步 #
🌐 Next steps