OracleDB vector store
OracleVector stores embeddings in Oracle Database VECTOR columns and exposes them through Mastra's vector interface. Each logical Mastra vector index is mapped to an Oracle vector table through a registry table, while metadata is stored as Oracle JSON for structured filtering.
InstallationDirect link to Installation
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/oracledb@latest
pnpm add @mastra/oracledb@latest
yarn add @mastra/oracledb@latest
bun add @mastra/oracledb@latest
UsageDirect link to Usage
import { OracleVector } from '@mastra/oracledb'
const vector = new OracleVector({
id: 'oracle-vector',
user: process.env.ORACLE_DATABASE_USER,
password: process.env.ORACLE_DATABASE_PASSWORD,
connectString: process.env.ORACLE_DATABASE_CONNECT_STRING,
})
await vector.createIndex({
indexName: 'memory_messages',
dimension: 1536,
metric: 'cosine',
})
await vector.upsert({
indexName: 'memory_messages',
vectors: [embedding],
metadata: [{ resource_id: 'user-1', thread_id: 'thread-1' }],
})
const results = await vector.query({
indexName: 'memory_messages',
queryVector,
topK: 5,
filter: { resource_id: 'user-1' },
})
By default, OracleVector uses exact search with no approximate vector index. Configure IVF or HNSW when your dataset and latency requirements need approximate search.
Constructor optionsDirect link to Constructor options
Pass Oracle connection options (user, password, connectString, pool, wallet options, or externalAuth) directly, or pass poolManager to share the pool used by OracleStore. The vector-specific options are:
id:
poolManager?:
OracleStore.schemaName?:
tablePrefix?:
registryTableName?:
defaultIndexConfig?:
defaultMetadataIndexes?:
defaultVectorFormat?:
upsertBatchSize?:
executeMany call. The full upsert commits once after all batches succeed.Constructor examplesDirect link to Constructor examples
Shared pool with OracleStoreDirect link to Shared pool with OracleStore
import { OracleStore, OracleVector } from '@mastra/oracledb'
const storage = new OracleStore({ id: 'oracle-storage', user, password, connectString })
const vector = new OracleVector({
id: 'oracle-vector',
poolManager: storage.getPoolManager(),
})
For Autonomous Database and mTLS connections, pass walletLocation, walletPassword, and configDir in the same constructor.
MethodsDirect link to Methods
createIndex()Direct link to createindex
Creates the registry row, physical Oracle vector table, metadata indexes, and optionally an Oracle vector index.
indexName:
dimension:
metric?:
hamming and jaccard.vectorFormat?:
indexConfig?:
none means exact search with no approximate vector index.buildIndex?:
indexConfig.type is ivf or hnsw.metadataIndexes?:
OracleVectorIndexConfigDirect link to oraclevectorindexconfig
type?:
accuracy?:
ivf.neighborPartitions?:
hnsw.neighbors?:
hnsw.efConstruction?:
Index configurationDirect link to Index configuration
await vector.createIndex({
indexName: 'support_articles',
dimension: 1536,
metric: 'cosine',
indexConfig: {
type: 'ivf',
accuracy: 95,
ivf: {
neighborPartitions: 32,
},
},
})
The default is indexConfig: { type: 'none' }, which uses exact search and requires no approximate index tuning. Use IVF or HNSW only when your data volume and latency requirements justify approximate search. HNSW is configured with indexConfig: { type: 'hnsw', hnsw: { neighbors, efConstruction } } and requires Oracle Vector Pool memory, which configureVectorMemory() can allocate for local or self-managed databases.
upsert()Direct link to upsert
indexName:
vectors:
metadata?:
vectors.ids?:
query()Direct link to query
indexName:
queryVector:
topK?:
filter?:
includeVector?:
minScore?:
queryMode?:
targetAccuracy?:
listIndexes()Direct link to listindexes
Returns the logical Mastra index names recorded in the Oracle vector registry table.
describeIndex()Direct link to describeindex
Returns Oracle index metadata, including the physical table name, dimension, vector count, metric, index type, vector format, and configured accuracy.
deleteIndex()Direct link to deleteindex
Deletes the Oracle vector table and removes the registry entry for the logical index.
updateVector()Direct link to updatevector
Update vectors by ID or metadata filter. Either id or filter must be provided, but not both. The update object may include vector, metadata, or both.
await vector.updateVector({
indexName: 'support_articles',
id: 'doc-1',
update: { metadata: { status: 'reviewed' } },
})
deleteVector()Direct link to deletevector
Deletes a single vector by ID.
deleteVectors()Direct link to deletevectors
Deletes multiple vectors by IDs or by metadata filter. Either ids or filter must be provided, but not both.
buildIndex()Direct link to buildindex
Builds an Oracle vector index for an existing logical index. If the resolved index type is none, this method is a no-op.
rebuildIndex()Direct link to rebuildindex
Drops and recreates the Oracle vector index for an existing logical index, typically after changing approximate-index tuning.
Index diagnosticsDirect link to Index diagnostics
Use getIndexStatus({ indexName }) to inspect Oracle catalog status, and indexAccuracyQuery({ indexName, queryVector, topK, targetAccuracy }) to run DBMS_VECTOR.INDEX_ACCURACY_QUERY for approximate indexes.
configureVectorMemory()Direct link to configurevectormemory
Allocates Oracle Vector Pool memory, which HNSW indexes require. This calls ALTER SYSTEM SET VECTOR_MEMORY_SIZE, so it requires a privileged connection such as SYSDBA or SYSTEM.
size:
K, M, or G (for example "512M").scope?:
disconnect()Direct link to disconnect
Closes the Oracle pool when OracleVector created the pool manager. If you provide pool or poolManager, you own that lifecycle.
Metadata filtersDirect link to Metadata filters
OracleVector accepts Mastra's standard metadata filter syntax. Filters are translated into Oracle JSON predicates with bound values:
- scalar comparisons use
JSON_VALUE - array, existence, and element-match checks use
JSON_EXISTS - regex filters use
REGEXP_LIKE - string contains filters use case-insensitive
LIKE
const results = await vector.query({
indexName: 'memory_messages',
queryVector,
topK: 5,
filter: {
resource_id: 'user-1',
tags: { $contains: 'support' },
score: { $gte: 0.8 },
$or: [{ source: 'docs' }, { source: 'tickets' }],
},
})
Metadata is stored as native Oracle JSON, so the rows are also readable directly with standard Oracle JDBC tools such as DBeaver and SQL Developer.
Use ORACLEDB_PROMPT when an agent should generate Oracle-compatible metadata filters for createVectorQueryTool():
import { Agent } from '@mastra/core/agent'
import { createVectorQueryTool } from '@mastra/rag'
import { fastembed } from '@mastra/fastembed'
import { ORACLEDB_PROMPT } from '@mastra/oracledb'
const vectorQueryTool = createVectorQueryTool({
vectorStoreName: 'oracle',
indexName: 'support_articles',
model: fastembed,
enableFilter: true,
})
export const ragAgent = new Agent({
id: 'oracle-rag-agent',
name: 'Oracle RAG Agent',
model: 'openai/gpt-5.6-sol',
instructions: `
Use the retrieval tool when you need source context.
Available metadata fields: resource_id, thread_id, source, category, tags.
${ORACLEDB_PROMPT}
`,
tools: { vectorQueryTool },
})
Response typesDirect link to Response types
Query results are returned in this format:
interface QueryResult {
id: string
score: number
metadata: Record<string, any>
vector?: number[]
}
Usage exampleDirect link to Usage example
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { fastembed } from '@mastra/fastembed'
import { OracleStore, OracleVector } from '@mastra/oracledb'
const storage = new OracleStore({
id: 'oracle-storage',
user: process.env.ORACLE_DATABASE_USER,
password: process.env.ORACLE_DATABASE_PASSWORD,
connectString: process.env.ORACLE_DATABASE_CONNECT_STRING,
})
const vector = new OracleVector({
id: 'oracle-vector',
poolManager: storage.getPoolManager(),
})
export const oracleAgent = new Agent({
id: 'oracle-agent',
name: 'Oracle Agent',
instructions: 'You are an assistant with OracleDB-backed memory and semantic recall.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
storage,
vector,
embedder: fastembed,
options: {
semanticRecall: { topK: 3, messageRange: 2 },
},
}),
})