@mastra/mongodb 0.0.0-vnext-inngest-20250508131921 → 0.0.0-vnextAgentNetwork-20250527091247

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,7 +60,7 @@ async function createIndexAndWait(
60
60
  metric: 'cosine' | 'euclidean' | 'dotproduct',
61
61
  ) {
62
62
  await vectorDB.createIndex({ indexName, dimension, metric });
63
- await vectorDB.waitForIndexReady(indexName);
63
+ await vectorDB.waitForIndexReady({ indexName });
64
64
  const created = await waitForCondition(
65
65
  async () => {
66
66
  const cols = await vectorDB.listIndexes();
@@ -75,7 +75,7 @@ async function createIndexAndWait(
75
75
  // Delete index (collection) and wait until it is removed
76
76
  async function deleteIndexAndWait(vectorDB: MongoDBVector, indexName: string) {
77
77
  try {
78
- await vectorDB.deleteIndex(indexName);
78
+ await vectorDB.deleteIndex({ indexName });
79
79
  const deleted = await waitForCondition(
80
80
  async () => {
81
81
  const cols = await vectorDB.listIndexes();
@@ -105,7 +105,7 @@ describe('MongoDBVector Integration Tests', () => {
105
105
  // Cleanup any existing collections
106
106
  try {
107
107
  const cols = await vectorDB.listIndexes();
108
- await Promise.all(cols.map(c => vectorDB.deleteIndex(c)));
108
+ await Promise.all(cols.map(c => vectorDB.deleteIndex({ indexName: c })));
109
109
  const deleted = await waitForCondition(async () => (await vectorDB.listIndexes()).length === 0, 30000, 2000);
110
110
  if (!deleted) throw new Error('Timed out waiting for collections to be deleted');
111
111
  } catch (error) {
@@ -119,12 +119,12 @@ describe('MongoDBVector Integration Tests', () => {
119
119
 
120
120
  afterAll(async () => {
121
121
  try {
122
- await vectorDB.deleteIndex(testIndexName);
122
+ await vectorDB.deleteIndex({ indexName: testIndexName });
123
123
  } catch (error) {
124
124
  console.error('Failed to delete test collection:', error);
125
125
  }
126
126
  try {
127
- await vectorDB.deleteIndex(testIndexName2);
127
+ await vectorDB.deleteIndex({ indexName: testIndexName2 });
128
128
  } catch (error) {
129
129
  console.error('Failed to delete test collection:', error);
130
130
  }
@@ -137,7 +137,7 @@ describe('MongoDBVector Integration Tests', () => {
137
137
  expect(cols).toContain(testIndexName);
138
138
 
139
139
  // Check stats (should be zero docs initially)
140
- const initialStats = await vectorDB.describeIndex(testIndexName);
140
+ const initialStats = await vectorDB.describeIndex({ indexName: testIndexName });
141
141
  expect(initialStats).toEqual({ dimension: 4, metric: 'cosine', count: 0 });
142
142
 
143
143
  // Upsert 4 vectors with metadata
@@ -153,7 +153,7 @@ describe('MongoDBVector Integration Tests', () => {
153
153
 
154
154
  // Wait for the document count to update (increased delay to 5000ms)
155
155
  await new Promise(resolve => setTimeout(resolve, 5000));
156
- const updatedStats = await vectorDB.describeIndex(testIndexName);
156
+ const updatedStats = await vectorDB.describeIndex({ indexName: testIndexName });
157
157
  expect(updatedStats.count).toEqual(4);
158
158
 
159
159
  // Query for similar vectors (delay again to allow for index update)
@@ -175,7 +175,7 @@ describe('MongoDBVector Integration Tests', () => {
175
175
  expect(filteredResults[0]?.metadata).toEqual({ label: 'vector2' });
176
176
 
177
177
  // Final stats should show > 0 documents
178
- const finalStats = await vectorDB.describeIndex(testIndexName);
178
+ const finalStats = await vectorDB.describeIndex({ indexName: testIndexName });
179
179
  expect(finalStats.count).toBeGreaterThan(0);
180
180
  });
181
181
 
@@ -379,7 +379,11 @@ describe('MongoDBVector Integration Tests', () => {
379
379
  const idToBeUpdated = ids[0];
380
380
  const newVector = [1, 2, 3, 4];
381
381
  const newMetaData = { test: 'updates' };
382
- await vectorDB.updateIndexById(indexName, idToBeUpdated, { vector: newVector, metadata: newMetaData });
382
+ await vectorDB.updateVector({
383
+ indexName,
384
+ id: idToBeUpdated,
385
+ update: { vector: newVector, metadata: newMetaData },
386
+ });
383
387
  await new Promise(resolve => setTimeout(resolve, 5000));
384
388
  const results = await vectorDB.query({
385
389
  indexName,
@@ -399,7 +403,7 @@ describe('MongoDBVector Integration Tests', () => {
399
403
  expect(ids).toHaveLength(4);
400
404
  const idToBeUpdated = ids[0];
401
405
  const newMetaData = { test: 'metadata only update' };
402
- await vectorDB.updateIndexById(indexName, idToBeUpdated, { metadata: newMetaData });
406
+ await vectorDB.updateVector({ indexName, id: idToBeUpdated, update: { metadata: newMetaData } });
403
407
  await new Promise(resolve => setTimeout(resolve, 5000));
404
408
  const results = await vectorDB.query({
405
409
  indexName,
@@ -419,7 +423,7 @@ describe('MongoDBVector Integration Tests', () => {
419
423
  expect(ids).toHaveLength(4);
420
424
  const idToBeUpdated = ids[0];
421
425
  const newVector = [1, 2, 3, 4];
422
- await vectorDB.updateIndexById(indexName, idToBeUpdated, { vector: newVector });
426
+ await vectorDB.updateVector({ indexName, id: idToBeUpdated, update: { vector: newVector } });
423
427
  await new Promise(resolve => setTimeout(resolve, 5000));
424
428
  const results = await vectorDB.query({
425
429
  indexName,
@@ -434,15 +438,24 @@ describe('MongoDBVector Integration Tests', () => {
434
438
  expect(updatedResult?.vector).toEqual(newVector);
435
439
  });
436
440
  it('should throw exception when no updates are given', async () => {
437
- await expect(vectorDB.updateIndexById(indexName, 'nonexistent-id', {})).rejects.toThrow('No updates provided');
441
+ await expect(vectorDB.updateVector({ indexName, id: 'nonexistent-id', update: {} })).rejects.toThrow(
442
+ 'No updates provided',
443
+ );
438
444
  });
439
445
  it('should delete the vector by id', async () => {
440
446
  const ids = await vectorDB.upsert({ indexName, vectors: testVectors });
441
447
  expect(ids).toHaveLength(4);
442
448
  const idToBeDeleted = ids[0];
443
- await vectorDB.deleteIndexById(indexName, idToBeDeleted);
449
+
450
+ const initialStats = await vectorDB.describeIndex({ indexName });
451
+
452
+ await vectorDB.deleteVector({ indexName, id: idToBeDeleted });
444
453
  const results = await vectorDB.query({ indexName, queryVector: [1, 0, 0, 0], topK: 2 });
445
454
  expect(results.map(res => res.id)).not.toContain(idToBeDeleted);
455
+
456
+ await new Promise(resolve => setTimeout(resolve, 5000)); // Wait for count to update
457
+ const finalStats = await vectorDB.describeIndex({ indexName });
458
+ expect(finalStats.count).toBe(initialStats.count - 1);
446
459
  });
447
460
  });
448
461
 
@@ -5,9 +5,10 @@ import type {
5
5
  CreateIndexParams,
6
6
  UpsertVectorParams,
7
7
  QueryVectorParams,
8
- ParamsToArgs,
9
- QueryVectorArgs,
10
- UpsertVectorArgs,
8
+ DescribeIndexParams,
9
+ DeleteIndexParams,
10
+ DeleteVectorParams,
11
+ UpdateVectorParams,
11
12
  } from '@mastra/core/vector';
12
13
  import type { VectorFilter } from '@mastra/core/vector/filter';
13
14
  import { MongoClient } from 'mongodb';
@@ -17,10 +18,6 @@ import { v4 as uuidv4 } from 'uuid';
17
18
  import { MongoDBFilterTranslator } from './filter';
18
19
 
19
20
  // Define necessary types and interfaces
20
- export type MongoDBUpsertArgs = [...UpsertVectorArgs, string[]?];
21
- export type MongoDBQueryArgs = [...QueryVectorArgs, string?];
22
- export type MongoDBUpsertParams = ParamsToArgs<MongoDBUpsertArgs>;
23
-
24
21
  export interface MongoDBUpsertVectorParams extends UpsertVectorParams {
25
22
  documents?: string[];
26
23
  }
@@ -29,6 +26,12 @@ export interface MongoDBQueryVectorParams extends QueryVectorParams {
29
26
  documentFilter?: VectorFilter;
30
27
  }
31
28
 
29
+ export interface MongoDBIndexReadyParams {
30
+ indexName: string;
31
+ timeoutMs?: number;
32
+ checkIntervalMs?: number;
33
+ }
34
+
32
35
  // Define the document interface
33
36
  interface MongoDBDocument extends Document {
34
37
  _id: string; // Explicitly declare '_id' as string
@@ -68,9 +71,7 @@ export class MongoDBVector extends MastraVector {
68
71
  await this.client.close();
69
72
  }
70
73
 
71
- async createIndex(params: CreateIndexParams): Promise<void> {
72
- const { indexName, dimension, metric = 'cosine' } = params;
73
-
74
+ async createIndex({ indexName, dimension, metric = 'cosine' }: CreateIndexParams): Promise<void> {
74
75
  if (!Number.isInteger(dimension) || dimension <= 0) {
75
76
  throw new Error('Dimension must be a positive integer');
76
77
  }
@@ -118,7 +119,19 @@ export class MongoDBVector extends MastraVector {
118
119
  await collection.updateOne({ _id: '__index_metadata__' }, { $set: { dimension, metric } }, { upsert: true });
119
120
  }
120
121
 
121
- async waitForIndexReady(indexName: string, timeoutMs: number = 60000, checkIntervalMs: number = 2000): Promise<void> {
122
+ /**
123
+ * Waits for the index to be ready.
124
+ *
125
+ * @param {string} indexName - The name of the index to wait for
126
+ * @param {number} timeoutMs - The maximum time in milliseconds to wait for the index to be ready (default: 60000)
127
+ * @param {number} checkIntervalMs - The interval in milliseconds at which to check if the index is ready (default: 2000)
128
+ * @returns A promise that resolves when the index is ready
129
+ */
130
+ async waitForIndexReady({
131
+ indexName,
132
+ timeoutMs = 60000,
133
+ checkIntervalMs = 2000,
134
+ }: MongoDBIndexReadyParams): Promise<void> {
122
135
  const collection = await this.getCollection(indexName, true);
123
136
  const indexNameInternal = `${indexName}_vector_index`;
124
137
 
@@ -135,15 +148,13 @@ export class MongoDBVector extends MastraVector {
135
148
  throw new Error(`Index "${indexNameInternal}" did not become ready within timeout`);
136
149
  }
137
150
 
138
- async upsert(params: MongoDBUpsertVectorParams): Promise<string[]> {
139
- const { indexName, vectors, metadata, ids, documents } = params;
140
-
151
+ async upsert({ indexName, vectors, metadata, ids, documents }: MongoDBUpsertVectorParams): Promise<string[]> {
141
152
  const collection = await this.getCollection(indexName);
142
153
 
143
154
  this.collectionForValidation = collection;
144
155
 
145
156
  // Get index stats to check dimension
146
- const stats = await this.describeIndex(indexName);
157
+ const stats = await this.describeIndex({ indexName });
147
158
 
148
159
  // Validate vector dimensions
149
160
  await this.validateVectorDimensions(vectors, stats.dimension);
@@ -187,9 +198,14 @@ export class MongoDBVector extends MastraVector {
187
198
  return generatedIds;
188
199
  }
189
200
 
190
- async query(params: MongoDBQueryVectorParams): Promise<QueryResult[]> {
191
- const { indexName, queryVector, topK = 10, filter, includeVector = false, documentFilter } = params;
192
-
201
+ async query({
202
+ indexName,
203
+ queryVector,
204
+ topK = 10,
205
+ filter,
206
+ includeVector = false,
207
+ documentFilter,
208
+ }: MongoDBQueryVectorParams): Promise<QueryResult[]> {
193
209
  const collection = await this.getCollection(indexName, true);
194
210
  const indexNameInternal = `${indexName}_vector_index`;
195
211
 
@@ -255,7 +271,13 @@ export class MongoDBVector extends MastraVector {
255
271
  return collections.map(col => col.name);
256
272
  }
257
273
 
258
- async describeIndex(indexName: string): Promise<IndexStats> {
274
+ /**
275
+ * Retrieves statistics about a vector index.
276
+ *
277
+ * @param {string} indexName - The name of the index to describe
278
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
279
+ */
280
+ async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {
259
281
  const collection = await this.getCollection(indexName, true);
260
282
 
261
283
  // Get the count of documents, excluding the metadata document
@@ -273,7 +295,7 @@ export class MongoDBVector extends MastraVector {
273
295
  };
274
296
  }
275
297
 
276
- async deleteIndex(indexName: string): Promise<void> {
298
+ async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {
277
299
  const collection = await this.getCollection(indexName, false); // Do not throw error if collection doesn't exist
278
300
  if (collection) {
279
301
  await collection.drop();
@@ -284,45 +306,64 @@ export class MongoDBVector extends MastraVector {
284
306
  }
285
307
  }
286
308
 
287
- async updateIndexById(
288
- indexName: string,
289
- id: string,
290
- update: { vector?: number[]; metadata?: Record<string, any> },
291
- ): Promise<void> {
292
- if (!update.vector && !update.metadata) {
293
- throw new Error('No updates provided');
294
- }
309
+ /**
310
+ * Updates a vector by its ID with the provided vector and/or metadata.
311
+ * @param indexName - The name of the index containing the vector.
312
+ * @param id - The ID of the vector to update.
313
+ * @param update - An object containing the vector and/or metadata to update.
314
+ * @param update.vector - An optional array of numbers representing the new vector.
315
+ * @param update.metadata - An optional record containing the new metadata.
316
+ * @returns A promise that resolves when the update is complete.
317
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
318
+ */
319
+ async updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void> {
320
+ try {
321
+ if (!update.vector && !update.metadata) {
322
+ throw new Error('No updates provided');
323
+ }
295
324
 
296
- const collection = await this.getCollection(indexName, true);
297
- const updateDoc: Record<string, any> = {};
325
+ const collection = await this.getCollection(indexName, true);
326
+ const updateDoc: Record<string, any> = {};
298
327
 
299
- if (update.vector) {
300
- updateDoc[this.embeddingFieldName] = update.vector;
301
- }
328
+ if (update.vector) {
329
+ const stats = await this.describeIndex({ indexName });
330
+ await this.validateVectorDimensions([update.vector], stats.dimension);
331
+ updateDoc[this.embeddingFieldName] = update.vector;
332
+ }
302
333
 
303
- if (update.metadata) {
304
- // Normalize metadata in updates too
305
- const normalizedMeta = Object.keys(update.metadata).reduce(
306
- (acc, key) => {
307
- acc[key] =
308
- update.metadata![key] instanceof Date ? update.metadata![key].toISOString() : update.metadata![key];
309
- return acc;
310
- },
311
- {} as Record<string, any>,
312
- );
334
+ if (update.metadata) {
335
+ // Normalize metadata in updates too
336
+ const normalizedMeta = Object.keys(update.metadata).reduce(
337
+ (acc, key) => {
338
+ acc[key] =
339
+ update.metadata![key] instanceof Date ? update.metadata![key].toISOString() : update.metadata![key];
340
+ return acc;
341
+ },
342
+ {} as Record<string, any>,
343
+ );
344
+
345
+ updateDoc[this.metadataFieldName] = normalizedMeta;
346
+ }
313
347
 
314
- updateDoc[this.metadataFieldName] = normalizedMeta;
348
+ await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
349
+ } catch (error: any) {
350
+ throw new Error(`Failed to update vector by id: ${id} for index name: ${indexName}: ${error.message}`);
315
351
  }
316
-
317
- await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
318
352
  }
319
353
 
320
- async deleteIndexById(indexName: string, id: string): Promise<void> {
354
+ /**
355
+ * Deletes a vector by its ID.
356
+ * @param indexName - The name of the index containing the vector.
357
+ * @param id - The ID of the vector to delete.
358
+ * @returns A promise that resolves when the deletion is complete.
359
+ * @throws Will throw an error if the deletion operation fails.
360
+ */
361
+ async deleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {
321
362
  try {
322
363
  const collection = await this.getCollection(indexName, true);
323
364
  await collection.deleteOne({ _id: id });
324
365
  } catch (error: any) {
325
- throw new Error(`Failed to delete index by id: ${id} for index name: ${indexName}: ${error.message}`);
366
+ throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
326
367
  }
327
368
  }
328
369
 
@@ -1,8 +0,0 @@
1
- services:
2
- mongodb:
3
- image: mongodb/mongodb-atlas-local
4
- environment:
5
- MONGODB_INITDB_ROOT_USERNAME: mongodb
6
- MONGODB_INITDB_ROOT_PASSWORD: mongodb
7
- ports:
8
- - 27018:27017