Lance vector store
The LanceVectorStore class provides vector search using LanceDB, an embedded vector database built on the Lance columnar format. It offers efficient storage and fast similarity search for both local development and production deployments.
Factory methodDirect link to Factory method
The LanceVectorStore uses a factory pattern for creation. You should use the static create() method rather than the constructor directly.
uri:
options?:
Constructor examplesDirect link to Constructor examples
You can create a LanceVectorStore instance using the static create method:
import { LanceVectorStore } from '@mastra/lance'
// Connect to a local database
const vectorStore = await LanceVectorStore.create('/path/to/db')
// Connect to a LanceDB cloud database
const cloudStore = await LanceVectorStore.create('db://host:port')
// Connect to a cloud database with options
const s3Store = await LanceVectorStore.create('s3://bucket/db', {
storageOptions: { timeout: '60s' },
})
MethodsDirect link to Methods
createIndex()Direct link to createindex
tableName:
indexName:
dimension:
metric?:
indexConfig?:
LanceIndexConfigDirect link to lanceindexconfig
type:
ivfflat:
ivfpq:
ivfflat with lower recall.hnsw:
numPartitions?:
numSubVectors?:
ivfpqhnsw?:
m?:
efConstruction?:
createTable()Direct link to createtable
tableName:
data:
options?:
upsert()Direct link to upsert
tableName:
vectors:
metadata?:
ids?:
query()Direct link to query
tableName:
queryVector:
topK?:
filter?:
includeVector?:
columns?:
includeAllColumns?:
listTables()Direct link to listtables
Returns an array of table names as strings.
const tables = await vectorStore.listTables()
// ['my_vectors', 'embeddings', 'documents']
getTableSchema()Direct link to gettableschema
tableName:
Returns the schema of the specified table.
deleteTable()Direct link to deletetable
tableName:
deleteAllTables()Direct link to deletealltables
Deletes all tables in the database.
listIndexes()Direct link to listindexes
Returns an array of index names as strings.
describeIndex()Direct link to describeindex
indexName:
Returns information about the index:
interface IndexStats {
dimension: number
count: number
metric: 'cosine' | 'euclidean' | 'dotproduct'
}
getIndexCoverage()Direct link to getindexcoverage
tableName?:
indexName when omitted.indexName?:
tableName is omitted, matching upsert() and query().Returns one entry per index on the table:
interface LanceIndexCoverage {
indexName: string
indexType: string
columns: string[]
numIndexedRows: number
numUnindexedRows: number
}
optimize()Direct link to optimize
Runs LanceDB table maintenance. It compacts data files, adds rows written since the index was built to the existing index, and removes old table versions. Mastra never calls it automatically. Concurrent calls for the same table in one process share a single run.
tableName?:
indexName when omitted.indexName?:
tableName is omitted.cleanupOlderThan?:
deleteUnverified?:
Returns LanceDB OptimizeStats (compaction and pruning counts).
When to optimizeDirect link to When to optimize
upsert() writes rows outside the existing vector index. query() still returns those rows by scanning them without the index, so results stay complete, but queries get slower as unindexed rows grow. LanceDB's fastSearch() skips unindexed rows entirely.
optimize() adds new rows to the existing index without retraining it. If your data distribution has changed a lot, rebuild the index with deleteIndex() and createIndex() instead.
LanceDB suggests optimizing after roughly 100,000 modified rows or 20 write operations. Use getIndexCoverage() to build your own policy:
const [coverage] = await store.getIndexCoverage({ indexName: 'docs' })
const total = coverage.numIndexedRows + coverage.numUnindexedRows
if (coverage.numUnindexedRows >= 1_000 && coverage.numUnindexedRows / total >= 0.1) {
await store.optimize({ indexName: 'docs' })
}
Managed LanceDB Cloud and Enterprise maintain tables automatically, so you don't need to call optimize() there.
deleteIndex()Direct link to deleteindex
indexName:
updateVector()Direct link to updatevector
Update a single vector by ID or by metadata filter. Either id or filter must be provided, but not both.
indexName:
id?:
filter?:
update:
deleteVector()Direct link to deletevector
indexName:
id:
deleteVectors()Direct link to deletevectors
Delete multiple vectors by IDs or by metadata filter. Either ids or filter must be provided, but not both.
indexName:
ids?:
filter?:
close()Direct link to close
Closes the database connection.
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[] // Only included if includeVector is true
document?: string // Document text if available
}
Error handlingDirect link to Error handling
The store throws typed errors that can be caught:
try {
await store.query({
tableName: 'my_vectors',
queryVector: queryVector,
})
} catch (error) {
if (error instanceof Error) {
console.log(error.message)
}
}
Best practicesDirect link to Best practices
- Use the appropriate index type for your use case:
- HNSW for better recall and performance when memory isn't constrained
- IVF for better memory efficiency with large datasets
- For optimal performance with large datasets, consider adjusting
numPartitionsandnumSubVectorsvalues - Use
close()method to properly close connections when done with the database - Store metadata with a consistent schema to simplify filtering operations