Upstash Vector Store
The UpstashVector class provides vector search using Upstash Vector , a serverless vector database service that provides vector similarity search with metadata filtering capabilities and hybrid search support.
Constructor Options
url:
token:
Methods
createIndex()
Note: This method is a no-op for Upstash as indexes are created automatically.
indexName:
dimension:
metric?:
upsert()
indexName:
vectors:
sparseVectors?:
metadata?:
ids?:
query()
indexName:
queryVector:
sparseVector?:
topK?:
filter?:
includeVector?:
fusionAlgorithm?:
queryMode?:
listIndexes()
Returns an array of index names (namespaces) as strings.
describeIndex()
indexName:
Returns:
interface IndexStats {
dimension: number;
count: number;
metric: "cosine" | "euclidean" | "dotproduct";
}
deleteIndex()
indexName:
updateVector()
indexName:
id:
update:
The update
object can have the following properties:
vector
(optional): An array of numbers representing the new dense vector.sparseVector
(optional): A sparse vector object withindices
andvalues
arrays for hybrid indexes.metadata
(optional): A record of key-value pairs for metadata.
deleteVector()
indexName:
id:
Attempts to delete an item by its ID from the specified index. Logs an error message if the deletion fails.
Hybrid Vector Search
Upstash Vector supports hybrid search that combines semantic search (dense vectors) with keyword-based search (sparse vectors) for improved relevance and accuracy.
Basic Hybrid Usage
import { UpstashVector } from '@mastra/upstash';
const vectorStore = new UpstashVector({
url: process.env.UPSTASH_VECTOR_URL,
token: process.env.UPSTASH_VECTOR_TOKEN
});
// Upsert vectors with both dense and sparse components
const denseVectors = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]];
const sparseVectors = [
{ indices: [1, 5, 10], values: [0.8, 0.6, 0.4] },
{ indices: [2, 6, 11], values: [0.7, 0.5, 0.3] }
];
await vectorStore.upsert({
indexName: 'hybrid-index',
vectors: denseVectors,
sparseVectors: sparseVectors,
metadata: [{ title: 'Document 1' }, { title: 'Document 2' }]
});
// Query with hybrid search
const results = await vectorStore.query({
indexName: 'hybrid-index',
queryVector: [0.1, 0.2, 0.3],
sparseVector: { indices: [1, 5], values: [0.9, 0.7] },
topK: 10
});
Advanced Hybrid Search Options
import { FusionAlgorithm, QueryMode } from '@upstash/vector';
// Query with specific fusion algorithm
const fusionResults = await vectorStore.query({
indexName: 'hybrid-index',
queryVector: [0.1, 0.2, 0.3],
sparseVector: { indices: [1, 5], values: [0.9, 0.7] },
fusionAlgorithm: FusionAlgorithm.RRF,
topK: 10
});
// Dense-only search
const denseResults = await vectorStore.query({
indexName: 'hybrid-index',
queryVector: [0.1, 0.2, 0.3],
queryMode: QueryMode.DENSE,
topK: 10
});
// Sparse-only search
const sparseResults = await vectorStore.query({
indexName: 'hybrid-index',
queryVector: [0.1, 0.2, 0.3], // Still required for index structure
sparseVector: { indices: [1, 5], values: [0.9, 0.7] },
queryMode: QueryMode.SPARSE,
topK: 10
});
Updating Hybrid Vectors
// Update both dense and sparse components
await vectorStore.updateVector({
indexName: 'hybrid-index',
id: 'vector-id',
update: {
vector: [0.2, 0.3, 0.4],
sparseVector: { indices: [2, 7, 12], values: [0.9, 0.8, 0.6] },
metadata: { title: 'Updated Document' }
}
});
Response Types
Query results are returned in this format:
interface QueryResult {
id: string;
score: number;
metadata: Record<string, any>;
vector?: number[]; // Only included if includeVector is true
}
Error Handling
The store throws typed errors that can be caught:
try {
await store.query({
indexName: "index_name",
queryVector: queryVector,
});
} catch (error) {
if (error instanceof VectorStoreError) {
console.log(error.code); // 'connection_failed' | 'invalid_dimension' | etc
console.log(error.details); // Additional error context
}
}
Environment Variables
Required environment variables:
UPSTASH_VECTOR_URL
: Your Upstash Vector database URLUPSTASH_VECTOR_TOKEN
: Your Upstash Vector API token