DocsRAGVector Databases

Vector Storage in Mastra

After generating embeddings, you need to store them in a database that supports vector similarity search. Mastra provides flexible options for vector storage, supporting both embedded and dedicated vector databases.

Choosing a Vector Database

When selecting a vector database, consider:

  • Infrastructure: Do you want to use your existing PostgreSQL database (with PgVector) or a dedicated vector database (Pinecone, Qdrant)?
  • Scale: How many vectors will you store and query? Dedicated solutions like Pinecone often handle larger scales better.
  • Query Performance: Need sub-second queries over millions of vectors? Consider specialized databases like Qdrant.
  • Management: Are you comfortable managing another database, or prefer using your existing PostgreSQL setup?

Supported databases

PostgreSQL with PgVector

Best for teams already using PostgreSQL who want to minimize infrastructure complexity:

 
import { PgVector } from '@mastra/rag';
 
const pgVector = new PgVector(process.env.POSTGRES_CONNECTION_STRING);
 
// Create an index (dimension = 1536 for text-embedding-ada-002)
await pgVector.createIndex("embeddings", 1536);
 
// Store embeddings with metadata
await pgVector.upsert(
  "embeddings",
  embeddings,
  chunks.map(chunk => ({ text: chunk.text }))
);

Pinecone

Ideal for production deployments needing scalability:

 
import { PineconeVector } from '@mastra/rag';
 
const pinecone = new PineconeVector(process.env.PINECONE_API_KEY);
 
// Create an index
await pinecone.createIndex("my-index", 1536);
 
// Store embeddings
await pinecone.upsert(
  "my-index",
  embeddings,
  chunks.map(chunk => ({ text: chunk.text }))
);

Qdrant

Best for high-performance vector search:

 
import { QdrantVector } from '@mastra/rag';
 
const qdrant = new QdrantVector({
  url: process.env.QDRANT_URL,
  apiKey: process.env.QDRANT_API_KEY
});
 
// Create collection
await qdrant.createCollection("my-collection", 1536);
 
// Store embeddings
await qdrant.upsert(
  "my-collection",
  embeddings,
  chunks.map(chunk => ({ text: chunk.text }))
);

Adding Metadata

All vector stores support adding metadata to your vectors, which enables filtering during retrieval:

// Store embeddings with rich metadata
await vectorStore.upsert(
  "embeddings",
  embeddings,
  chunks.map(chunk => ({
    text: chunk.text,
    source: chunk.source,
    category: chunk.category,
    timestamp: new Date().toISOString()
  }))
);

Performance Considerations

  • Indexing: Create appropriate indexes before bulk insertions
  • Batch Size: Use bath oeprations for large insertions
  • Metadata: Only store metadata you’ll query against
  • Dimensions: Match embedding dimensions to your model (eg., 1536 for text-embedding-ada-002)

Examples

For complete examples of different vector store implementations, see:


MIT 2025 © Nextra.