@mastra/lance 1.1.0-alpha.0 → 1.1.1-alpha.0

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
@@ -2645,7 +2645,8 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2645
2645
  includeVector = false,
2646
2646
  topK = 10,
2647
2647
  columns = [],
2648
- includeAllColumns = false
2648
+ includeAllColumns = false,
2649
+ metric
2649
2650
  }) {
2650
2651
  const resolvedTableName = tableName ?? indexName;
2651
2652
  if (!queryVector) {
@@ -2683,7 +2684,11 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2683
2684
  return [];
2684
2685
  }
2685
2686
  const table = await this.lanceClient.openTable(resolvedTableName);
2686
- let query = table.search(queryVector);
2687
+ const resolvedMetric = await this.resolveQueryMetric(table, {
2688
+ columnName: tableName ? indexName : "vector",
2689
+ explicitMetric: metric
2690
+ });
2691
+ let query = table.vectorSearch(queryVector).distanceType(this.mastraMetricToLance(resolvedMetric));
2687
2692
  if (filter && Object.keys(filter).length > 0) {
2688
2693
  const whereClause = this.filterTranslator(filter);
2689
2694
  this.logger.debug(`Where clause generated: ${whereClause}`);
@@ -2704,6 +2709,9 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2704
2709
  if (!selectColumns.includes("id")) {
2705
2710
  selectColumns.push("id");
2706
2711
  }
2712
+ if (!selectColumns.includes("_distance")) {
2713
+ selectColumns.push("_distance");
2714
+ }
2707
2715
  query = query.select(selectColumns);
2708
2716
  }
2709
2717
  query = query.limit(topK);
@@ -2724,7 +2732,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2724
2732
  metadata,
2725
2733
  vector: includeVector && result.vector ? Array.isArray(result.vector) ? result.vector : Array.from(result.vector) : void 0,
2726
2734
  document: result.document,
2727
- score: result._distance
2735
+ score: this.distanceToScore(result._distance, resolvedMetric)
2728
2736
  };
2729
2737
  });
2730
2738
  } catch (error) {
@@ -2739,6 +2747,85 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2739
2747
  );
2740
2748
  }
2741
2749
  }
2750
+ /**
2751
+ * Maps a Mastra distance metric to the LanceDB distance type.
2752
+ */
2753
+ mastraMetricToLance(metric) {
2754
+ switch (metric) {
2755
+ case "euclidean":
2756
+ return "l2";
2757
+ case "dotproduct":
2758
+ return "dot";
2759
+ case "cosine":
2760
+ default:
2761
+ return "cosine";
2762
+ }
2763
+ }
2764
+ /**
2765
+ * Determines the distance metric to use for a query.
2766
+ *
2767
+ * Precedence: the table's vector index metric wins when an index exists because
2768
+ * LanceDB requires indexed searches to use the same distance type the index was
2769
+ * trained with; otherwise an explicitly provided metric is used; otherwise it
2770
+ * defaults to 'cosine'.
2771
+ */
2772
+ async resolveQueryMetric(table, {
2773
+ columnName,
2774
+ explicitMetric
2775
+ }) {
2776
+ try {
2777
+ const indices = await table.listIndices();
2778
+ const matchingIndices = indices.filter((index) => index.columns?.includes(columnName));
2779
+ for (const index of matchingIndices.length > 0 ? matchingIndices : indices) {
2780
+ const stats = await table.indexStats(index.name);
2781
+ const resolved = this.lanceMetricToMastra(stats?.distanceType);
2782
+ if (resolved) {
2783
+ if (explicitMetric && explicitMetric !== resolved) {
2784
+ this.logger.warn(
2785
+ `Ignoring query metric "${explicitMetric}" because Lance index "${index.name}" uses "${resolved}".`
2786
+ );
2787
+ }
2788
+ return resolved;
2789
+ }
2790
+ }
2791
+ } catch (error) {
2792
+ this.logger.debug("Failed to resolve metric from Lance index stats.", error);
2793
+ }
2794
+ return explicitMetric ?? "cosine";
2795
+ }
2796
+ lanceMetricToMastra(metric) {
2797
+ switch (metric) {
2798
+ case "l2":
2799
+ return "euclidean";
2800
+ case "dot":
2801
+ return "dotproduct";
2802
+ case "cosine":
2803
+ return "cosine";
2804
+ default:
2805
+ return void 0;
2806
+ }
2807
+ }
2808
+ /**
2809
+ * Converts a LanceDB `_distance` (smaller = more similar) into a Mastra similarity
2810
+ * `score` (larger = more similar), consistent with every other Mastra vector store.
2811
+ *
2812
+ * - cosine: LanceDB returns cosine distance (`1 - cosine_similarity`), so `1 - distance`
2813
+ * recovers the cosine similarity.
2814
+ * - dotproduct: LanceDB's dot distance is `1 - dot_product`, so `1 - distance` recovers
2815
+ * the dot product (matching `@mastra/pg`).
2816
+ * - euclidean: LanceDB returns squared L2 distance for `l2`, so use its square root
2817
+ * before mapping into (0, 1] (matching `@mastra/pg`).
2818
+ */
2819
+ distanceToScore(distance, metric) {
2820
+ switch (metric) {
2821
+ case "euclidean":
2822
+ return 1 / (1 + Math.sqrt(distance));
2823
+ case "dotproduct":
2824
+ case "cosine":
2825
+ default:
2826
+ return 1 - distance;
2827
+ }
2828
+ }
2742
2829
  filterTranslator(filter) {
2743
2830
  const processFilterKeys = (filterObj) => {
2744
2831
  const result = {};
@@ -3031,14 +3118,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3031
3118
  } else {
3032
3119
  table = await this.lanceClient.openTable(resolvedTableName);
3033
3120
  }
3034
- let metricType;
3035
- if (metric === "euclidean") {
3036
- metricType = "l2";
3037
- } else if (metric === "dotproduct") {
3038
- metricType = "dot";
3039
- } else if (metric === "cosine") {
3040
- metricType = "cosine";
3041
- }
3121
+ const metricType = this.mastraMetricToLance(metric);
3042
3122
  const rowCount = await table.countRows();
3043
3123
  if (rowCount < 256) {
3044
3124
  this.logger.warn(
@@ -3143,7 +3223,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3143
3223
  const dimension = vectorField?.type?.["listSize"] || 0;
3144
3224
  return {
3145
3225
  dimension,
3146
- metric: stats.distanceType,
3226
+ metric: this.lanceMetricToMastra(stats.distanceType),
3147
3227
  count: stats.numIndexedRows
3148
3228
  };
3149
3229
  }