Skip to content
Storage

存储向量

Insert and update vector embeddings with metadata using the JavaScript SDK or Postgres.

一旦你创建了桶和索引,就可以开始存储向量了。向量可以包含可选的元数据,用于在查询时进行过滤和增强。

🌐 Once you've created a bucket and index, you can start storing vectors. Vectors can include optional metadata for filtering and enrichment during queries.

基础向量插入 #

🌐 Basic vector insertion

import { } from '@supabase/supabase-js'
const = ('https://your-project-id.supabase.co', 'your-service-key')
// Get bucket and index
const = ...('embeddings')
const = .('documents-openai')
// Insert vectors
const { } = await .({
: [
{
: 'doc-1',
: {
: [0.1, 0.2, 0.3 /* ... rest of embedding ... */],
},
: {
: 'Getting Started with Vector Buckets',
: 'documentation',
},
},
{
: 'doc-2',
: {
: [0.4, 0.5, 0.6 /* ... rest of embedding ... */],
},
: {
: 'Advanced Vector Search',
: 'blog',
},
},
],
})
if () {
.('Error storing vectors:', )
} else {
.('✓ Vectors stored successfully')
}

存储来自 Embeddings API 的向量 #

🌐 Storing vectors from Embeddings API

使用大型语言模型 API 生成嵌入并直接存储:

🌐 Generate embeddings using an LLM API and store them directly:

import { createClient } from '@supabase/supabase-js'
import OpenAI from 'openai'
const supabase = createClient('https://your-project-id.supabase.co', 'your-service-key')
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
})
// Documents to embed and store
const documents = [
{ id: '1', title: 'How to Train Your AI', content: 'Guide for training models...' },
{ id: '2', title: 'Vector Search Best Practices', content: 'Tips for semantic search...' },
{
id: '3',
title: 'Building RAG Systems',
content: 'Implementing retrieval-augmented generation...',
},
]
// Generate embeddings
const embeddings = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: documents.map((doc) => doc.content),
})
// Prepare vectors for storage
const vectors = documents.map((doc, index) => ({
key: doc.id,
data: {
float32: embeddings.data[index].embedding,
},
metadata: {
title: doc.title,
source: 'knowledge_base',
created_at: new Date().toISOString(),
},
}))
// Store vectors in batches (max 500 per request)
const bucket = supabase.storage.vectors.from('embeddings')
const vectorIndex = bucket.index('documents-openai')
for (let i = 0; i < vectors.length; i += 500) {
const batch = vectors.slice(i, i + 500)
const { error } = await vectorIndex.putVectors({ vectors: batch })
if (error) {
console.error(`Error storing batch ${i / 500 + 1}:`, error)
} else {
console.log(`✓ Stored batch ${i / 500 + 1} (${batch.length} vectors)`)
}
}

更新向量 #

🌐 Updating vectors

const index = bucket.index('documents-openai')
// Update a vector (same key)
const { error } = await index.putVectors({
vectors: [
{
key: 'doc-1',
data: {
float32: [0.15, 0.25, 0.35 /* ... updated embedding ... */],
},
metadata: {
title: 'Getting Started with Vector Buckets - Updated',
updated_at: new Date().toISOString(),
},
},
],
})
if (!error) {
console.log('✓ Vector updated successfully')
}

删除向量 #

🌐 Deleting vectors

const index = bucket.index('documents-openai')
// Delete specific vectors
const { error } = await index.deleteVectors({
keys: ['doc-1', 'doc-2'],
})
if (!error) {
console.log('✓ Vectors deleted successfully')
}

元数据最佳实践 #

🌐 Metadata best practices

元数据让向量更有用,因为它可以实现过滤和提供上下文:

🌐 Metadata makes vectors more useful by enabling filtering and context:

const vectors = [
{
key: 'product-001',
data: { float32: [...] },
metadata: {
product_id: 'prod-001',
category: 'electronics',
price: 299.99,
in_stock: true,
tags: ['laptop', 'portable'],
description: 'High-performance ultrabook'
}
},
{
key: 'product-002',
data: { float32: [...] },
metadata: {
product_id: 'prod-002',
category: 'electronics',
price: 99.99,
in_stock: true,
tags: ['headphones', 'wireless'],
description: 'Noise-cancelling wireless headphones'
}
}
]
const { error } = await index.putVectors({ vectors })

元数据字段指南 #

🌐 Metadata field guidelines

  • 保持轻量 - 查询结果会返回元数据,因此大值会增加响应大小
  • 使用一致的类型 - 在不同向量中使用相同的数据类型存储相同的字段
  • 索引关键字段 - 标记你要筛选的字段以提升查询性能
  • 避免嵌套对象 - 虽然支持,但扁平结构更容易过滤

批量处理大数据集 #

🌐 Batch processing large datasets

为了高效存储大量向量:

🌐 For storing large numbers of vectors efficiently:

import { createClient } from '@supabase/supabase-js'
import fs from 'fs'
const supabase = createClient(...)
const index = supabase.storage.vectors
.from('embeddings')
.index('documents-openai')
// Read embeddings from file
const embeddingsFile = fs.readFileSync('embeddings.jsonl', 'utf-8')
const lines = embeddingsFile.split('\n').filter(line => line.trim())
const vectors = lines.map((line, idx) => {
const { key, embedding, metadata } = JSON.parse(line)
return {
key,
data: { float32: embedding },
metadata
}
})
// Process in batches
const BATCH_SIZE = 500
let processed = 0
for (let i = 0; i < vectors.length; i += BATCH_SIZE) {
const batch = vectors.slice(i, i + BATCH_SIZE)
try {
const { error } = await index.putVectors({ vectors: batch })
if (error) throw error
processed += batch.length
console.log(`Progress: ${processed}/${vectors.length}`)
} catch (error) {
console.error(`Batch failed at offset ${i}:`, error)
// Optionally implement retry logic
}
}
console.log('✓ All vectors stored successfully')

性能优化 #

🌐 Performance optimization

批量操作 #

🌐 Batch operations

为了更好的性能,尽量使用批量操作:

🌐 Always use batch operations for better performance:

// ❌ Inefficient - Multiple requests
for (const vector of vectors) {
await index.putVectors({ vectors: [vector] })
}
// ✅ Efficient - Single batch operation
await index.putVectors({ vectors })

元数据注意事项 #

🌐 Metadata considerations

保持元数据简洁:

🌐 Keep metadata concise:

// ❌ Large metadata
metadata: {
full_document_text: 'Very long document content...',
detailed_analysis: { /* large object */ }
}
// ✅ Lean metadata
metadata: {
doc_id: 'doc-123',
category: 'news',
summary: 'Brief summary'
}

下一步 #

🌐 Next steps