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

Convex vector store

The ConvexVector class provides vector storage and similarity search using Convex. It stores embeddings inside Convex and performs cosine similarity search in the Mastra adapter.

Development-scale search

ConvexVector reads matching vectors through the Mastra storage handler and filters them in JavaScript. It then computes cosine similarity and sorts the results before returning the top matches. Use it for local development, tests, and small datasets.

For production vector search on Convex, use ConvexNativeVector. It uses the Convex native vectorSearch API, which requires a deployed Convex vector index and a Convex action.

Installation
Installation的直接链接

npm install @mastra/convex@latest

Convex setup
Convex setup的直接链接

Before using ConvexVector, you need to set up the Convex schema and storage handler. See Convex Storage Setup for setup instructions.

Constructor options
Constructor options的直接链接

deploymentUrl:

string
Convex deployment URL (e.g., https://your-project.convex.cloud)

adminAuthToken:

string
Convex admin authentication token

storageFunction?:

string
= mastra/storage:handle
Path to the storage mutation function

Constructor examples
Constructor examples的直接链接

Basic configuration
Basic configuration的直接链接

import { ConvexVector } from '@mastra/convex'

const vectorStore = new ConvexVector({
id: 'convex-vectors',
deploymentUrl: 'https://your-project.convex.cloud',
adminAuthToken: 'your-admin-token',
})

Use ConvexNativeVector for production vector workloads. It stores vectors in a dedicated Convex table and queries a schema-defined Convex vector index.

In convex/schema.ts, define a dedicated table for each Mastra vector index:

convex/schema.ts
import { defineSchema } from 'convex/server'
import { defineMastraNativeVectorTable } from '@mastra/convex/schema'

export default defineSchema({
docs_vectors: defineMastraNativeVectorTable({
dimensions: 1536,
}),
})

In convex/mastra/nativeVector.ts, export the native vector handlers:

convex/mastra/nativeVector.ts
import {
mastraNativeVectorAction,
mastraNativeVectorMutation,
mastraNativeVectorQuery,
} from '@mastra/convex/server'

export const query = mastraNativeVectorAction
export const read = mastraNativeVectorQuery
export const write = mastraNativeVectorMutation

In your Mastra app, configure ConvexNativeVector with the deployed table and vector index:

src/mastra/index.ts
import { ConvexNativeVector } from '@mastra/convex'

const vectorStore = new ConvexNativeVector({
id: 'convex-native-vectors',
deploymentUrl: process.env.CONVEX_URL!,
adminAuthToken: process.env.CONVEX_ADMIN_KEY!,
indexes: {
docs: {
tableName: 'docs_vectors',
vectorIndexName: 'by_embedding',
dimension: 1536,
},
},
})

const results = await vectorStore.query({
indexName: 'docs',
queryVector: embedding,
topK: 10,
})

For native filter support, declare filter fields in your Convex schema. The native vector handlers copy matching metadata fields to top-level document fields when vectors are written.

convex/schema.ts
import { defineSchema, defineTable } from 'convex/server'
import { v } from 'convex/values'

export default defineSchema({
docs_vectors: defineTable({
id: v.string(),
embedding: v.array(v.float64()),
metadata: v.optional(v.any()),
tenantId: v.string(),
})
.index('by_record_id', ['id'])
.vectorIndex('by_embedding', {
vectorField: 'embedding',
dimensions: 1536,
filterFields: ['tenantId'],
}),
})
src/mastra/index.ts
const vectorStore = new ConvexNativeVector({
id: 'convex-native-vectors',
deploymentUrl: process.env.CONVEX_URL!,
adminAuthToken: process.env.CONVEX_ADMIN_KEY!,
indexes: {
docs: {
tableName: 'docs_vectors',
dimension: 1536,
filterFields: ['tenantId'],
},
},
})

await vectorStore.upsert({
indexName: 'docs',
ids: ['chunk-1'],
vectors: [embedding],
metadata: [{ tenantId: 'acme', text: 'Account setup guide' }],
})

const results = await vectorStore.query({
indexName: 'docs',
queryVector: embedding,
filter: { tenantId: 'acme' },
})

ConvexNativeVector supports Convex native vector filter shapes: one equality field, or $or of equality fields. It doesn't support metadata-only queries, filter-based updates, or filter-based deletes. Use vector IDs for updates and deletes.

Custom storage function
Custom storage function的直接链接

const vectorStore = new ConvexVector({
id: 'convex-vectors',
deploymentUrl: 'https://your-project.convex.cloud',
adminAuthToken: 'your-admin-token',
storageFunction: 'custom/path:handler',
})

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'
= cosine
Distance metric for similarity search (only cosine is currently supported)
await vectorStore.createIndex({
indexName: 'my_vectors',
dimension: 1536,
})

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)
await vectorStore.upsert({
indexName: "my_vectors",
vectors: [[0.1, 0.2, 0.3, ...]],
metadata: [{ label: "example" }],
ids: ["vec-1"],
});

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
const results = await vectorStore.query({
indexName: "my_vectors",
queryVector: [0.1, 0.2, 0.3, ...],
topK: 5,
filter: { category: "documents" },
});

listIndexes()
listindexes的直接链接

Returns an array of index names as strings.

const indexes = await vectorStore.listIndexes()
// ["my_vectors", "embeddings", ...]

describeIndex()
describeindex的直接链接

indexName:

string
Name of the index to describe

Returns:

interface IndexStats {
dimension: number
count: number
metric: 'cosine' | 'euclidean' | 'dotproduct'
}

deleteIndex()
deleteindex的直接链接

indexName:

string
Name of the index to delete

Deletes the index and all its vectors.

await vectorStore.deleteIndex({ indexName: 'my_vectors' })

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
// Update by ID
await vectorStore.updateVector({
indexName: 'my_vectors',
id: 'vector123',
update: {
vector: [0.1, 0.2, 0.3],
metadata: { label: 'updated' },
},
})

// Update by filter
await vectorStore.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
await vectorStore.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)
// Delete by IDs
await vectorStore.deleteVectors({
indexName: 'my_vectors',
ids: ['vec1', 'vec2', 'vec3'],
})

// Delete by filter
await vectorStore.deleteVectors({
indexName: 'my_vectors',
filter: { status: 'archived' },
})

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
}

Metadata filtering
Metadata filtering的直接链接

ConvexVector supports metadata filtering with operators. These filters are applied by the adapter after vectors are loaded from Convex.

// Simple equality
const results = await vectorStore.query({
indexName: 'my_vectors',
queryVector: embedding,
filter: { category: 'documents' },
})

// Comparison operators
const results = await vectorStore.query({
indexName: 'my_vectors',
queryVector: embedding,
filter: {
price: { $gt: 100 },
status: { $in: ['active', 'pending'] },
},
})

// Logical operators
const results = await vectorStore.query({
indexName: 'my_vectors',
queryVector: embedding,
filter: {
$and: [{ category: 'electronics' }, { price: { $lte: 500 } }],
},
})

Supported filter operators
Supported filter operators的直接链接

OperatorDescription
$neNot equal to
$gtGreater than
$gteGreater than or equal
$ltLess than
$lteLess than or equal
$inIn array
$ninNot in array
$andLogical AND
$orLogical OR

Architecture
Architecture的直接链接

ConvexVector stores each index in its own table named mastra_vector_{indexName}. Each record has the following structure:

  • id: Unique vector identifier
  • embedding: The vector data (array of floats)
  • metadata: Optional JSON metadata

Vector similarity search is performed with cosine similarity in the Mastra adapter. This keeps setup flexible, but it's not designed for large production vector collections.

ConvexNativeVector stores each Mastra vector index in a dedicated Convex table. Its queries call a Convex action that uses ctx.vectorSearch, then load the matched documents through a Convex query. This follows the Convex native vector search model:

  • Vector indexes are declared in convex/schema.ts.
  • Vector search runs from a Convex action.
  • topK must be between 1 and 256.
  • Filters must target fields listed in the Convex vector index filterFields.
  • Use one dedicated table per Mastra vector index to avoid cross-index results.

Use an external vector database when you need runtime-defined index creation at runtime, metadata-only queries, complex filter operators, filter-based bulk updates or deletes, or result limits above Convex's native vector search cap.