跳到主要内容
非官方简体中文翻译,内容版权归 Mastra 所有,遵循 Apache-2.0 许可。

PG vector store

The PgVector class provides vector search using PostgreSQL with pgvector extension. It provides reliable vector similarity search capabilities within your existing PostgreSQL database.

Constructor options
Constructor options的直接链接

connectionString?:

string
PostgreSQL connection URL

host?:

string
PostgreSQL server host

port?:

number
PostgreSQL server port

database?:

string
PostgreSQL database name

user?:

string
PostgreSQL user

password?:

string
PostgreSQL password

ssl?:

boolean | ConnectionOptions
Enable SSL or provide custom SSL configuration

schemaName?:

string
The name of the schema you want the vector store to use. Will use the default schema if not provided.

max?:

number
Maximum number of pool connections (default: 20)

idleTimeoutMillis?:

number
Idle connection timeout in milliseconds (default: 30000)

pgPoolOptions?:

PoolConfig
Additional pg pool configuration options

disableInit?:

boolean
= false
When true, automatic DDL (schema, extension, table, and index creation) inside createIndex is skipped. Useful for CI/CD pipelines where schema and indexes are managed separately and the runtime database role lacks DDL privileges. Can also be enabled with the MASTRA_DISABLE_STORAGE_INIT environment variable.

Constructor examples
Constructor examples的直接链接

Connection String
Connection String的直接链接

import { PgVector } from '@mastra/pg'

const vectorStore = new PgVector({
id: 'pg-vector',
connectionString: 'postgresql://user:password@localhost:5432/mydb',
})

Host/Port/Database Configuration
Host/Port/Database Configuration的直接链接

const vectorStore = new PgVector({
id: 'pg-vector',
host: 'localhost',
port: 5432,
database: 'mydb',
user: 'postgres',
password: 'password',
})

Advanced Configuration
Advanced Configuration的直接链接

const vectorStore = new PgVector({
id: 'pg-vector',
connectionString: 'postgresql://user:password@localhost:5432/mydb',
schemaName: 'custom_schema',
max: 30,
idleTimeoutMillis: 60000,
pgPoolOptions: {
connectionTimeoutMillis: 5000,
allowExitOnIdle: true,
},
})

Methods
Methods的直接链接

createIndex()
createindex的直接链接

indexName:

string
Name of the index to create

dimension:

number
Vector dimension (must match your embedding model)

metric?:

'cosine' | 'euclidean' | 'dotproduct' | 'hamming' | 'jaccard'
= 'cosine' ('hamming' when vectorType is 'bit')
Distance metric for similarity search. 'hamming' and 'jaccard' are only valid with vectorType 'bit', and 'jaccard' requires an HNSW index.

vectorType?:

'vector' | 'halfvec' | 'bit' | 'sparsevec'
= vector
pgvector storage type for the embeddings

indexConfig?:

IndexConfig
= { type: 'ivfflat' }
Index configuration

buildIndex?:

boolean
= true
Whether to build the index

metadataIndexes?:

string[]
Array of metadata field names to create btree indexes on. Improves query performance when filtering by these metadata fields.

IndexConfig
indexconfig的直接链接

type:

'flat' | 'hnsw' | 'ivfflat'
= ivfflat
Index type
string

flat:

flat
Sequential scan (no index) that performs exhaustive search.

ivfflat:

ivfflat
Clusters vectors into lists for approximate search.

hnsw:

hnsw
Graph-based index offering fast search times and high recall.

ivf?:

IVFConfig
IVF configuration
object

lists?:

number
Number of lists. If not specified, automatically calculated based on dataset size. (Minimum 100, Maximum 4000)

hnsw?:

HNSWConfig
HNSW configuration
object

m?:

number
Maximum number of connections per node (default: 8)

efConstruction?:

number
Build-time complexity (default: 32)

Memory Requirements
Memory Requirements的直接链接

HNSW indexes require substantial shared memory during construction. For 100K vectors:

  • Small dimensions (64d): ~60MB with default settings
  • Medium dimensions (256d): ~180MB with default settings
  • Large dimensions (384d+): ~250MB+ with default settings

Higher M values or efConstruction values will increase memory requirements substantially. Adjust your system's shared memory limits if needed.

upsert()
upsert的直接链接

indexName:

string
Name of the index to upsert vectors into

vectors:

number[][]
Array of embedding vectors

metadata?:

Record<string, any>[]
Metadata for each vector

ids?:

string[]
Optional vector IDs (auto-generated if not provided)

query()
query的直接链接

indexName:

string
Name of the index to query

queryVector:

number[]
Query vector

topK?:

number
= 10
Number of results to return

filter?:

Record<string, any>
Metadata filters

includeVector?:

boolean
= false
Whether to include the vector in the result

minScore?:

number
= -1
Minimum similarity score threshold

ef?:

number
HNSW search parameter. Higher values improve accuracy at the cost of speed.

probes?:

number
IVFFlat search parameter. Number of lists to visit during search.

listIndexes()
listindexes的直接链接

Returns an array of index names as strings.

describeIndex()
describeindex的直接链接

indexName:

string
Name of the index to describe

Returns:

interface PGIndexStats {
dimension: number
count: number
metric: 'cosine' | 'euclidean' | 'dotproduct' | 'hamming' | 'jaccard'
type: 'flat' | 'hnsw' | 'ivfflat'
vectorType: 'vector' | 'halfvec' | 'bit' | 'sparsevec'
config: {
m?: number
efConstruction?: number
lists?: number
probes?: number
}
}

count is an exact SELECT COUNT(*), which scans the whole table, so avoid calling describeIndex() on a hot path for a large index. Reads and writes never pay for it: they only use the index metadata, which comes from the Postgres catalog.

deleteIndex()
deleteindex的直接链接

indexName:

string
Name of the index to delete

updateVector()
updatevector的直接链接

Update a single vector by ID or by metadata filter. Either id or filter must be provided, but not both.

indexName:

string
Name of the index containing the vector

id?:

string
ID of the vector to update (mutually exclusive with filter)

filter?:

Record<string, any>
Metadata filter to identify vector(s) to update (mutually exclusive with id)

update:

{ vector?: number[]; metadata?: Record<string, any>; }
Object containing the vector and/or metadata to update

Updates an existing vector by ID or filter. At least one of vector or metadata must be provided in the update object.

// Update by ID
await pgVector.updateVector({
indexName: 'my_vectors',
id: 'vector123',
update: {
vector: [0.1, 0.2, 0.3],
metadata: { label: 'updated' },
},
})

// Update by filter
await pgVector.updateVector({
indexName: 'my_vectors',
filter: { category: 'product' },
update: {
metadata: { status: 'reviewed' },
},
})

deleteVector()
deletevector的直接链接

indexName:

string
Name of the index containing the vector

id:

string
ID of the vector to delete

Deletes a single vector by ID from the specified index.

await pgVector.deleteVector({ indexName: 'my_vectors', id: 'vector123' })

deleteVectors()
deletevectors的直接链接

Delete multiple vectors by IDs or by metadata filter. Either ids or filter must be provided, but not both.

indexName:

string
Name of the index containing the vectors to delete

ids?:

string[]
Array of vector IDs to delete (mutually exclusive with filter)

filter?:

Record<string, any>
Metadata filter to identify vectors to delete (mutually exclusive with ids)

disconnect()
disconnect的直接链接

Closes the database connection pool. Should be called when done using the store.

buildIndex()
buildindex的直接链接

indexName:

string
Name of the index to define

metric?:

'cosine' | 'euclidean' | 'dotproduct' | 'hamming' | 'jaccard'
= cosine
Distance metric for similarity search

indexConfig:

IndexConfig
Configuration for the index type and parameters

Builds or rebuilds an index with specified metric and configuration. Will drop any existing index before creating the new one.

// Define HNSW index
await pgVector.buildIndex('my_vectors', 'cosine', {
type: 'hnsw',
hnsw: {
m: 8,
efConstruction: 32,
},
})

// Define IVF index
await pgVector.buildIndex('my_vectors', 'cosine', {
type: 'ivfflat',
ivf: {
lists: 100,
},
})

// Define flat index
await pgVector.buildIndex('my_vectors', 'cosine', {
type: 'flat',
})

Response types
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
Error handling的直接链接

The store throws MastraError instances from @mastra/core/error:

import { MastraError } from '@mastra/core/error'

try {
await store.query({
indexName: 'index_name',
queryVector: queryVector,
})
} catch (error) {
if (error instanceof MastraError) {
console.log(error.id) // 'MASTRA_VECTOR_PG_QUERY_FAILED'
console.log(error.domain) // 'MASTRA_VECTOR'
console.log(error.category) // 'USER' | 'THIRD_PARTY'
console.log(error.details) // Additional error context
}
}

Index configuration guide
Index configuration guide的直接链接

Performance Optimization
Performance Optimization的直接链接

IVFFlat Tuning
IVFFlat Tuning的直接链接

  • lists parameter: Set to sqrt(n) * 2 where n is the number of vectors
  • More lists = better accuracy but slower build time
  • Fewer lists = faster build but potentially lower accuracy

HNSW Tuning
HNSW Tuning的直接链接

  • m parameter:
    • 8-16: Moderate accuracy, lower memory
    • 16-32: High accuracy, moderate memory
    • 32-64: Very high accuracy, high memory
  • efConstruction:
    • 32-64: Fast build, good quality
    • 64-128: Slower build, better quality
    • 128-256: Slowest build, best quality

Index Recreation Behavior
Index Recreation Behavior的直接链接

The system automatically detects configuration changes and only rebuilds indexes when necessary:

  • Same configuration: Index is kept (no recreation)
  • Changed configuration: Index is dropped and rebuilt
  • This prevents the performance issues from unnecessary index recreations

Best practices
Best practices的直接链接

  • Regularly evaluate your index configuration to ensure optimal performance.
  • Adjust parameters like lists and m based on dataset size and query requirements.
  • Monitor index performance using describeIndex() to track usage
  • Rebuild indexes periodically to maintain efficiency, especially after substantial data changes

Direct pool access
Direct pool access的直接链接

The PgVector class exposes its underlying PostgreSQL connection pool as a public field:

pgVector.pool // instance of pg.Pool

Direct pool access supports advanced operations such as direct SQL queries, transactions, or pool-state monitoring. When using the pool directly:

  • You are responsible for releasing clients (client.release()) after use.
  • The pool remains accessible after calling disconnect(), but new queries will fail.
  • Direct access bypasses any validation or transaction logic provided by PgVector methods.

This design supports advanced use cases but requires careful resource management by the user.

Usage example
Usage example的直接链接

Local embeddings with fastembed
Local embeddings with fastembed的直接链接

Embeddings are numeric vectors used by memory's semanticRecall to retrieve related messages by meaning (not keywords). This setup uses @mastra/fastembed to generate vector embeddings.

Install fastembed to get started:

npm install @mastra/fastembed@latest

Add the following to your agent:

src/mastra/agents/example-pg-agent.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { PostgresStore, PgVector } from '@mastra/pg'
import { fastembed } from '@mastra/fastembed'

export const pgAgent = new Agent({
id: 'pg-agent',
name: 'PG Agent',
instructions:
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
storage: new PostgresStore({
id: 'pg-agent-storage',
connectionString: process.env.DATABASE_URL!,
}),
vector: new PgVector({
id: 'pg-agent-vector',
connectionString: process.env.DATABASE_URL!,
}),
embedder: fastembed,
options: {
lastMessages: 10,
semanticRecall: {
topK: 3,
messageRange: 2,
},
},
}),
})