@mastra/mongodb 1.0.0-beta.0 → 1.0.0-beta.2

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.
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { saveScorePayloadSchema } from '@mastra/core/evals';
11
11
 
12
12
  // package.json
13
13
  var package_default = {
14
- version: "1.0.0-beta.0"};
14
+ version: "1.0.0-beta.2"};
15
15
  var MongoDBFilterTranslator = class extends BaseFilterTranslator {
16
16
  getSupportedOperators() {
17
17
  return {
@@ -353,12 +353,17 @@ var MongoDBVector = class extends MastraVector {
353
353
  limit: topK
354
354
  };
355
355
  if (Object.keys(combinedFilter).length > 0) {
356
- const candidateIds = await collection.aggregate([{ $match: combinedFilter }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
356
+ const filterWithExclusion = {
357
+ $and: [{ _id: { $ne: "__index_metadata__" } }, combinedFilter]
358
+ };
359
+ const candidateIds = await collection.aggregate([{ $match: filterWithExclusion }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
357
360
  if (candidateIds.length > 0) {
358
361
  vectorSearch.filter = { _id: { $in: candidateIds } };
359
362
  } else {
360
363
  return [];
361
364
  }
365
+ } else {
366
+ vectorSearch.filter = { _id: { $ne: "__index_metadata__" } };
362
367
  }
363
368
  const pipeline = [
364
369
  {
@@ -479,7 +484,26 @@ var MongoDBVector = class extends MastraVector {
479
484
  * @returns A promise that resolves when the update is complete.
480
485
  * @throws Will throw an error if no updates are provided or if the update operation fails.
481
486
  */
482
- async updateVector({ indexName, id, update }) {
487
+ async updateVector(params) {
488
+ const { indexName, update } = params;
489
+ if ("id" in params && params.id && "filter" in params && params.filter) {
490
+ throw new MastraError({
491
+ id: "STORAGE_MONGODB_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE_PARAMS",
492
+ domain: ErrorDomain.STORAGE,
493
+ category: ErrorCategory.USER,
494
+ details: { indexName },
495
+ text: "id and filter are mutually exclusive - provide only one"
496
+ });
497
+ }
498
+ if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
499
+ throw new MastraError({
500
+ id: "STORAGE_MONGODB_VECTOR_UPDATE_MISSING_PARAMS",
501
+ domain: ErrorDomain.STORAGE,
502
+ category: ErrorCategory.USER,
503
+ text: "Either id or filter must be provided",
504
+ details: { indexName }
505
+ });
506
+ }
483
507
  try {
484
508
  if (!update.vector && !update.metadata) {
485
509
  throw new Error("No updates provided");
@@ -501,17 +525,49 @@ var MongoDBVector = class extends MastraVector {
501
525
  );
502
526
  updateDoc[this.metadataFieldName] = normalizedMeta;
503
527
  }
504
- await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
528
+ if ("id" in params && params.id) {
529
+ await collection.findOneAndUpdate({ _id: params.id }, { $set: updateDoc });
530
+ } else if ("filter" in params && params.filter) {
531
+ const filter = params.filter;
532
+ if (!filter || Object.keys(filter).length === 0) {
533
+ throw new MastraError({
534
+ id: "STORAGE_MONGODB_VECTOR_UPDATE_EMPTY_FILTER",
535
+ domain: ErrorDomain.STORAGE,
536
+ category: ErrorCategory.USER,
537
+ details: { indexName },
538
+ text: "Cannot update with empty filter"
539
+ });
540
+ }
541
+ const mongoFilter = this.transformFilter(filter);
542
+ const transformedFilter = this.transformMetadataFilter(mongoFilter);
543
+ if (!transformedFilter || Object.keys(transformedFilter).length === 0) {
544
+ throw new MastraError({
545
+ id: "STORAGE_MONGODB_VECTOR_UPDATE_INVALID_FILTER",
546
+ domain: ErrorDomain.STORAGE,
547
+ category: ErrorCategory.USER,
548
+ details: { indexName },
549
+ text: "Filter produced empty query"
550
+ });
551
+ }
552
+ await collection.updateMany(transformedFilter, { $set: updateDoc });
553
+ }
505
554
  } catch (error) {
555
+ if (error instanceof MastraError) {
556
+ throw error;
557
+ }
558
+ const errorDetails = { indexName };
559
+ if ("id" in params && params.id) {
560
+ errorDetails.id = params.id;
561
+ }
562
+ if ("filter" in params && params.filter) {
563
+ errorDetails.filter = JSON.stringify(params.filter);
564
+ }
506
565
  throw new MastraError(
507
566
  {
508
567
  id: "STORAGE_MONGODB_VECTOR_UPDATE_VECTOR_FAILED",
509
568
  domain: ErrorDomain.STORAGE,
510
569
  category: ErrorCategory.THIRD_PARTY,
511
- details: {
512
- indexName,
513
- id
514
- }
570
+ details: errorDetails
515
571
  },
516
572
  error
517
573
  );
@@ -543,6 +599,83 @@ var MongoDBVector = class extends MastraVector {
543
599
  );
544
600
  }
545
601
  }
602
+ async deleteVectors({ indexName, filter, ids }) {
603
+ if (!filter && !ids) {
604
+ throw new MastraError({
605
+ id: "STORAGE_MONGODB_VECTOR_DELETE_MISSING_PARAMS",
606
+ domain: ErrorDomain.STORAGE,
607
+ category: ErrorCategory.USER,
608
+ details: { indexName },
609
+ text: "Either filter or ids must be provided"
610
+ });
611
+ }
612
+ if (filter && ids) {
613
+ throw new MastraError({
614
+ id: "STORAGE_MONGODB_VECTOR_DELETE_CONFLICTING_PARAMS",
615
+ domain: ErrorDomain.STORAGE,
616
+ category: ErrorCategory.USER,
617
+ details: { indexName },
618
+ text: "Cannot provide both filter and ids - they are mutually exclusive"
619
+ });
620
+ }
621
+ try {
622
+ const collection = await this.getCollection(indexName, true);
623
+ if (ids) {
624
+ if (ids.length === 0) {
625
+ throw new MastraError({
626
+ id: "STORAGE_MONGODB_VECTOR_DELETE_EMPTY_IDS",
627
+ domain: ErrorDomain.STORAGE,
628
+ category: ErrorCategory.USER,
629
+ details: { indexName },
630
+ text: "Cannot delete with empty ids array"
631
+ });
632
+ }
633
+ await collection.deleteMany({ _id: { $in: ids } });
634
+ } else {
635
+ if (!filter || Object.keys(filter).length === 0) {
636
+ throw new MastraError({
637
+ id: "STORAGE_MONGODB_VECTOR_DELETE_EMPTY_FILTER",
638
+ domain: ErrorDomain.STORAGE,
639
+ category: ErrorCategory.USER,
640
+ details: { indexName },
641
+ text: "Cannot delete with empty filter"
642
+ });
643
+ }
644
+ const mongoFilter = this.transformFilter(filter);
645
+ const transformedFilter = this.transformMetadataFilter(mongoFilter);
646
+ if (!transformedFilter || Object.keys(transformedFilter).length === 0) {
647
+ throw new MastraError({
648
+ id: "STORAGE_MONGODB_VECTOR_DELETE_INVALID_FILTER",
649
+ domain: ErrorDomain.STORAGE,
650
+ category: ErrorCategory.USER,
651
+ details: { indexName },
652
+ text: "Filter produced empty query"
653
+ });
654
+ }
655
+ const finalFilter = {
656
+ $and: [{ _id: { $ne: "__index_metadata__" } }, transformedFilter]
657
+ };
658
+ await collection.deleteMany(finalFilter);
659
+ }
660
+ } catch (error) {
661
+ if (error instanceof MastraError) {
662
+ throw error;
663
+ }
664
+ throw new MastraError(
665
+ {
666
+ id: "STORAGE_MONGODB_VECTOR_DELETE_VECTORS_FAILED",
667
+ domain: ErrorDomain.STORAGE,
668
+ category: ErrorCategory.THIRD_PARTY,
669
+ details: {
670
+ indexName,
671
+ ...filter && { filter: JSON.stringify(filter) },
672
+ ...ids && { idsCount: ids.length }
673
+ }
674
+ },
675
+ error
676
+ );
677
+ }
678
+ }
546
679
  // Private methods
547
680
  async getCollection(indexName, throwIfNotExists = true) {
548
681
  if (this.collections.has(indexName)) {
@@ -590,16 +723,26 @@ var MongoDBVector = class extends MastraVector {
590
723
  */
591
724
  transformMetadataFilter(filter) {
592
725
  if (!filter || typeof filter !== "object") return filter;
726
+ if (Array.isArray(filter)) {
727
+ return filter.map((item) => this.transformMetadataFilter(item));
728
+ }
593
729
  const transformed = {};
594
730
  for (const [key, value] of Object.entries(filter)) {
595
731
  if (key.startsWith("$")) {
596
732
  if (Array.isArray(value)) {
597
733
  transformed[key] = value.map((item) => this.transformMetadataFilter(item));
598
- } else {
734
+ } else if (typeof value === "object" && value !== null) {
599
735
  transformed[key] = this.transformMetadataFilter(value);
736
+ } else {
737
+ transformed[key] = value;
600
738
  }
601
739
  } else if (key.startsWith("metadata.")) {
602
- transformed[key] = value;
740
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
741
+ const hasOperator = Object.keys(value).some((k) => k.startsWith("$"));
742
+ transformed[key] = hasOperator ? value : value;
743
+ } else {
744
+ transformed[key] = value;
745
+ }
603
746
  } else if (this.isMetadataField(key)) {
604
747
  transformed[`metadata.${key}`] = value;
605
748
  } else {
@@ -2244,6 +2387,9 @@ var WorkflowsStorageMongoDB = class extends WorkflowsStorage {
2244
2387
  if (options.workflowName) {
2245
2388
  query["workflow_name"] = options.workflowName;
2246
2389
  }
2390
+ if (options.status) {
2391
+ query["snapshot.status"] = options.status;
2392
+ }
2247
2393
  if (options.fromDate) {
2248
2394
  query["createdAt"] = { $gte: options.fromDate };
2249
2395
  }