PG Vector Store
The PgVector class provides vector search using PostgreSQL with pgvector extension. It provides robust vector similarity search capabilities within your existing PostgreSQL database.
Constructor Options
connectionString:
Methods
createIndex()
indexName:
dimension:
metric?:
indexConfig?:
buildIndex?:
IndexConfig
type:
flat:
ivfflat:
hnsw:
ivf?:
lists?:
hnsw?:
m?:
efConstruction?:
Memory Requirements
HNSW indexes require significant 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 significantly. Adjust your system’s shared memory limits if needed.
upsert()
indexName:
vectors:
metadata?:
ids?:
query()
indexName:
vector:
topK?:
filter?:
includeVector?:
minScore?:
options?:
ef?:
probes?:
listIndexes()
Returns an array of index names as strings.
describeIndex()
indexName:
Returns:
interface PGIndexStats {
dimension: number;
count: number;
metric: "cosine" | "euclidean" | "dotproduct";
type: "flat" | "hnsw" | "ivfflat";
config: {
m?: number;
efConstruction?: number;
lists?: number;
probes?: number;
};
}
deleteIndex()
indexName:
updateIndexById()
indexName:
id:
update:
vector?:
metadata?:
Updates an existing vector by ID. At least one of vector or metadata must be provided.
// Update just the vector
await pgVector.updateIndexById("my_vectors", "vector123", {
vector: [0.1, 0.2, 0.3],
});
// Update just the metadata
await pgVector.updateIndexById("my_vectors", "vector123", {
metadata: { label: "updated" },
});
// Update both vector and metadata
await pgVector.updateIndexById("my_vectors", "vector123", {
vector: [0.1, 0.2, 0.3],
metadata: { label: "updated" },
});
deleteIndexById()
indexName:
id:
Deletes a single vector by ID from the specified index.
await pgVector.deleteIndexById("my_vectors", "vector123");
disconnect()
Closes the database connection pool. Should be called when done using the store.
buildIndex()
indexName:
metric?:
indexConfig:
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
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
}
}
Best Practices
- Regularly evaluate your index configuration to ensure optimal performance.
- Adjust parameters like
lists
andm
based on dataset size and query requirements. - Rebuild indexes periodically to maintain efficiency, especially after significant data changes.