@mastra/lance 1.0.0 → 1.0.1

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
@@ -2406,6 +2406,16 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2406
2406
  if (filter && Object.keys(filter).length > 0) {
2407
2407
  const whereClause = this.filterTranslator(filter);
2408
2408
  this.logger.debug(`Where clause generated: ${whereClause}`);
2409
+ const schema = await table.schema();
2410
+ const schemaColumns = new Set(schema.fields.map((f) => f.name));
2411
+ const filterColumns = this.extractFilterColumns(whereClause);
2412
+ const missingColumns = filterColumns.filter((col) => !schemaColumns.has(col));
2413
+ if (missingColumns.length > 0) {
2414
+ this.logger.debug(
2415
+ `Filter references columns not in schema: ${missingColumns.join(", ")}. Returning empty results.`
2416
+ );
2417
+ return [];
2418
+ }
2409
2419
  query = query.where(whereClause);
2410
2420
  }
2411
2421
  if (!includeAllColumns && columns.length > 0) {
@@ -2418,16 +2428,16 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2418
2428
  query = query.limit(topK);
2419
2429
  const results = await query.toArray();
2420
2430
  return results.map((result) => {
2421
- const flatMetadata = {};
2422
- Object.keys(result).forEach((key) => {
2423
- if (key !== "id" && key !== "score" && key !== "vector" && key !== "_distance") {
2424
- if (key.startsWith("metadata_")) {
2425
- const metadataKey = key.substring("metadata_".length);
2426
- flatMetadata[metadataKey] = result[key];
2427
- }
2431
+ let metadata = {};
2432
+ if (result._metadata_json) {
2433
+ try {
2434
+ metadata = JSON.parse(result._metadata_json);
2435
+ } catch {
2436
+ metadata = this.extractFlatMetadata(result);
2428
2437
  }
2429
- });
2430
- const metadata = this.unflattenObject(flatMetadata);
2438
+ } else {
2439
+ metadata = this.extractFlatMetadata(result);
2440
+ }
2431
2441
  return {
2432
2442
  id: String(result.id || ""),
2433
2443
  metadata,
@@ -2523,6 +2533,9 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2523
2533
  Object.entries(flattenedMetadata).forEach(([key, value]) => {
2524
2534
  rowData[key] = value;
2525
2535
  });
2536
+ rowData["_metadata_json"] = JSON.stringify(metadataItem);
2537
+ } else {
2538
+ rowData["_metadata_json"] = "";
2526
2539
  }
2527
2540
  return rowData;
2528
2541
  });
@@ -2721,7 +2734,9 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2721
2734
  `Table ${resolvedTableName} does not exist. Creating empty table with dimension ${dimension}.`
2722
2735
  );
2723
2736
  const initVector = new Array(dimension).fill(0);
2724
- table = await this.lanceClient.createTable(resolvedTableName, [{ id: "__init__", vector: initVector }]);
2737
+ table = await this.lanceClient.createTable(resolvedTableName, [
2738
+ { id: "__init__", vector: initVector, _metadata_json: "" }
2739
+ ]);
2725
2740
  try {
2726
2741
  await table.delete("id = '__init__'");
2727
2742
  } catch (deleteError) {
@@ -3069,6 +3084,17 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3069
3084
  Object.entries(update.metadata).forEach(([key, value]) => {
3070
3085
  rowData[`metadata_${key}`] = value;
3071
3086
  });
3087
+ const hasMetadataJson = schema.fields.some((f) => f.name === "_metadata_json");
3088
+ if (hasMetadataJson) {
3089
+ let existingMetadata = {};
3090
+ if (record._metadata_json) {
3091
+ try {
3092
+ existingMetadata = JSON.parse(record._metadata_json);
3093
+ } catch {
3094
+ }
3095
+ }
3096
+ rowData["_metadata_json"] = JSON.stringify({ ...existingMetadata, ...update.metadata });
3097
+ }
3072
3098
  }
3073
3099
  return rowData;
3074
3100
  });
@@ -3160,29 +3186,27 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3160
3186
  }
3161
3187
  }
3162
3188
  /**
3163
- * Converts a flattened object with keys using underscore notation back to a nested object.
3164
- * Example: { name: 'test', details_text: 'test' } → { name: 'test', details: { text: 'test' } }
3189
+ * Extracts column names referenced in a SQL WHERE clause.
3190
+ * Identifies metadata_* prefixed identifiers used in filter conditions.
3165
3191
  */
3166
- unflattenObject(obj) {
3167
- const result = {};
3168
- Object.keys(obj).forEach((key) => {
3169
- const value = obj[key];
3170
- const parts = key.split("_");
3171
- let current = result;
3172
- for (let i = 0; i < parts.length - 1; i++) {
3173
- const part = parts[i];
3174
- if (!part) continue;
3175
- if (!current[part] || typeof current[part] !== "object") {
3176
- current[part] = {};
3192
+ extractFilterColumns(whereClause) {
3193
+ const matches = whereClause.match(/metadata_\w+/g);
3194
+ return matches ? [...new Set(matches)] : [];
3195
+ }
3196
+ /**
3197
+ * Extracts metadata from flattened column names (legacy data without _metadata_json).
3198
+ * Returns keys as-is after stripping the 'metadata_' prefix, without any unflattening.
3199
+ */
3200
+ extractFlatMetadata(result) {
3201
+ const metadata = {};
3202
+ Object.keys(result).forEach((key) => {
3203
+ if (key !== "id" && key !== "score" && key !== "vector" && key !== "_distance" && key !== "_metadata_json") {
3204
+ if (key.startsWith("metadata_")) {
3205
+ metadata[key.substring("metadata_".length)] = result[key];
3177
3206
  }
3178
- current = current[part];
3179
- }
3180
- const lastPart = parts[parts.length - 1];
3181
- if (lastPart) {
3182
- current[lastPart] = value;
3183
3207
  }
3184
3208
  });
3185
- return result;
3209
+ return metadata;
3186
3210
  }
3187
3211
  async deleteVectors({ indexName, filter, ids }) {
3188
3212
  if (ids && filter) {