@lancedb/lancedb 0.5.1 → 0.7.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/Cargo.toml +3 -3
- package/biome.json +19 -3
- package/dist/arrow.d.ts +42 -7
- package/dist/arrow.js +6 -5
- package/dist/connection.d.ts +55 -29
- package/dist/connection.js +22 -74
- package/dist/embedding/embedding_function.d.ts +11 -3
- package/dist/embedding/embedding_function.js +36 -12
- package/dist/embedding/openai.d.ts +6 -5
- package/dist/embedding/openai.js +4 -2
- package/dist/embedding/registry.d.ts +10 -11
- package/dist/embedding/registry.js +4 -0
- package/dist/index.d.ts +51 -3
- package/dist/index.js +28 -4
- package/dist/merge.d.ts +54 -0
- package/dist/merge.js +64 -0
- package/dist/native.d.ts +34 -7
- package/dist/native.js +26 -9
- package/dist/query.d.ts +51 -16
- package/dist/query.js +122 -21
- package/dist/remote/client.d.ts +28 -0
- package/dist/remote/client.js +172 -0
- package/dist/remote/connection.d.ts +25 -0
- package/dist/remote/connection.js +110 -0
- package/dist/remote/index.d.ts +3 -0
- package/dist/remote/index.js +9 -0
- package/dist/remote/table.d.ts +42 -0
- package/dist/remote/table.js +179 -0
- package/dist/sanitize.d.ts +3 -2
- package/dist/sanitize.js +55 -1
- package/dist/table.d.ts +116 -25
- package/dist/table.js +117 -233
- package/dist/util.d.ts +14 -0
- package/dist/util.js +65 -0
- package/examples/ann_indexes.ts +49 -0
- package/examples/basic.ts +149 -0
- package/examples/embedding.ts +83 -0
- package/examples/filtering.ts +34 -0
- package/examples/jsconfig.json +27 -0
- package/examples/package-lock.json +79 -0
- package/examples/package.json +18 -0
- package/examples/search.ts +37 -0
- package/lancedb/arrow.ts +87 -24
- package/lancedb/connection.ts +115 -92
- package/lancedb/embedding/embedding_function.ts +48 -16
- package/lancedb/embedding/openai.ts +11 -6
- package/lancedb/embedding/registry.ts +38 -22
- package/lancedb/index.ts +101 -2
- package/lancedb/merge.ts +70 -0
- package/lancedb/query.ts +168 -39
- package/lancedb/remote/client.ts +221 -0
- package/lancedb/remote/connection.ts +201 -0
- package/lancedb/remote/index.ts +3 -0
- package/lancedb/remote/table.ts +226 -0
- package/lancedb/sanitize.ts +73 -1
- package/lancedb/table.ts +344 -101
- package/lancedb/util.ts +69 -0
- package/native.d.ts +208 -0
- package/nodejs-artifacts/arrow.d.ts +42 -7
- package/nodejs-artifacts/arrow.js +6 -5
- package/nodejs-artifacts/connection.d.ts +55 -29
- package/nodejs-artifacts/connection.js +22 -74
- package/nodejs-artifacts/embedding/embedding_function.d.ts +11 -3
- package/nodejs-artifacts/embedding/embedding_function.js +36 -12
- package/nodejs-artifacts/embedding/openai.d.ts +6 -5
- package/nodejs-artifacts/embedding/openai.js +4 -2
- package/nodejs-artifacts/embedding/registry.d.ts +10 -11
- package/nodejs-artifacts/embedding/registry.js +4 -0
- package/nodejs-artifacts/index.d.ts +51 -3
- package/nodejs-artifacts/index.js +28 -4
- package/nodejs-artifacts/merge.d.ts +54 -0
- package/nodejs-artifacts/merge.js +64 -0
- package/nodejs-artifacts/native.d.ts +34 -7
- package/nodejs-artifacts/native.js +26 -9
- package/nodejs-artifacts/query.d.ts +51 -16
- package/nodejs-artifacts/query.js +122 -21
- package/nodejs-artifacts/remote/client.d.ts +28 -0
- package/nodejs-artifacts/remote/client.js +172 -0
- package/nodejs-artifacts/remote/connection.d.ts +25 -0
- package/nodejs-artifacts/remote/connection.js +110 -0
- package/nodejs-artifacts/remote/index.d.ts +3 -0
- package/nodejs-artifacts/remote/index.js +9 -0
- package/nodejs-artifacts/remote/table.d.ts +42 -0
- package/nodejs-artifacts/remote/table.js +179 -0
- package/nodejs-artifacts/sanitize.d.ts +3 -2
- package/nodejs-artifacts/sanitize.js +55 -1
- package/nodejs-artifacts/table.d.ts +116 -25
- package/nodejs-artifacts/table.js +117 -233
- package/nodejs-artifacts/util.d.ts +14 -0
- package/nodejs-artifacts/util.js +65 -0
- package/package.json +25 -11
package/lancedb/table.ts
CHANGED
|
@@ -12,20 +12,37 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
Table as ArrowTable,
|
|
17
|
+
Data,
|
|
18
|
+
IntoVector,
|
|
19
|
+
Schema,
|
|
20
|
+
TableLike,
|
|
21
|
+
fromDataToBuffer,
|
|
22
|
+
fromTableToBuffer,
|
|
23
|
+
fromTableToStreamBuffer,
|
|
24
|
+
isArrowTable,
|
|
25
|
+
makeArrowTable,
|
|
26
|
+
tableFromIPC,
|
|
27
|
+
} from "./arrow";
|
|
28
|
+
import { CreateTableOptions } from "./connection";
|
|
16
29
|
|
|
17
|
-
import { getRegistry } from "./embedding/registry";
|
|
30
|
+
import { EmbeddingFunctionConfig, getRegistry } from "./embedding/registry";
|
|
18
31
|
import { IndexOptions } from "./indices";
|
|
32
|
+
import { MergeInsertBuilder } from "./merge";
|
|
19
33
|
import {
|
|
20
34
|
AddColumnsSql,
|
|
21
35
|
ColumnAlteration,
|
|
22
36
|
IndexConfig,
|
|
37
|
+
IndexStatistics,
|
|
23
38
|
OptimizeStats,
|
|
24
39
|
Table as _NativeTable,
|
|
25
40
|
} from "./native";
|
|
26
41
|
import { Query, VectorQuery } from "./query";
|
|
27
|
-
|
|
42
|
+
import { sanitizeTable } from "./sanitize";
|
|
43
|
+
import { IntoSql, toSQL } from "./util";
|
|
28
44
|
export { IndexConfig } from "./native";
|
|
45
|
+
|
|
29
46
|
/**
|
|
30
47
|
* Options for adding data to a table.
|
|
31
48
|
*/
|
|
@@ -81,19 +98,15 @@ export interface OptimizeOptions {
|
|
|
81
98
|
* Closing a table is optional. It not closed, it will be closed when it is garbage
|
|
82
99
|
* collected.
|
|
83
100
|
*/
|
|
84
|
-
export class Table {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
/** Construct a Table. Internal use only. */
|
|
88
|
-
constructor(inner: _NativeTable) {
|
|
89
|
-
this.inner = inner;
|
|
101
|
+
export abstract class Table {
|
|
102
|
+
[Symbol.for("nodejs.util.inspect.custom")](): string {
|
|
103
|
+
return this.display();
|
|
90
104
|
}
|
|
105
|
+
/** Returns the name of the table */
|
|
106
|
+
abstract get name(): string;
|
|
91
107
|
|
|
92
108
|
/** Return true if the table has not been closed */
|
|
93
|
-
isOpen(): boolean
|
|
94
|
-
return this.inner.isOpen();
|
|
95
|
-
}
|
|
96
|
-
|
|
109
|
+
abstract isOpen(): boolean;
|
|
97
110
|
/**
|
|
98
111
|
* Close the table, releasing any underlying resources.
|
|
99
112
|
*
|
|
@@ -101,39 +114,44 @@ export class Table {
|
|
|
101
114
|
*
|
|
102
115
|
* Any attempt to use the table after it is closed will result in an error.
|
|
103
116
|
*/
|
|
104
|
-
close(): void
|
|
105
|
-
this.inner.close();
|
|
106
|
-
}
|
|
107
|
-
|
|
117
|
+
abstract close(): void;
|
|
108
118
|
/** Return a brief description of the table */
|
|
109
|
-
display(): string
|
|
110
|
-
return this.inner.display();
|
|
111
|
-
}
|
|
112
|
-
|
|
119
|
+
abstract display(): string;
|
|
113
120
|
/** Get the schema of the table. */
|
|
114
|
-
|
|
115
|
-
const schemaBuf = await this.inner.schema();
|
|
116
|
-
const tbl = tableFromIPC(schemaBuf);
|
|
117
|
-
return tbl.schema;
|
|
118
|
-
}
|
|
119
|
-
|
|
121
|
+
abstract schema(): Promise<Schema>;
|
|
120
122
|
/**
|
|
121
123
|
* Insert records into this Table.
|
|
122
124
|
* @param {Data} data Records to be inserted into the Table
|
|
123
125
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
126
|
+
abstract add(data: Data, options?: Partial<AddDataOptions>): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Update existing records in the Table
|
|
129
|
+
* @param opts.values The values to update. The keys are the column names and the values
|
|
130
|
+
* are the values to set.
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* table.update({where:"x = 2", values:{"vector": [10, 10]}})
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
abstract update(
|
|
137
|
+
opts: {
|
|
138
|
+
values: Map<string, IntoSql> | Record<string, IntoSql>;
|
|
139
|
+
} & Partial<UpdateOptions>,
|
|
140
|
+
): Promise<void>;
|
|
141
|
+
/**
|
|
142
|
+
* Update existing records in the Table
|
|
143
|
+
* @param opts.valuesSql The values to update. The keys are the column names and the values
|
|
144
|
+
* are the values to set. The values are SQL expressions.
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* table.update({where:"x = 2", valuesSql:{"x": "x + 1"}})
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
abstract update(
|
|
151
|
+
opts: {
|
|
152
|
+
valuesSql: Map<string, string> | Record<string, string>;
|
|
153
|
+
} & Partial<UpdateOptions>,
|
|
154
|
+
): Promise<void>;
|
|
137
155
|
/**
|
|
138
156
|
* Update existing records in the Table
|
|
139
157
|
*
|
|
@@ -159,30 +177,15 @@ export class Table {
|
|
|
159
177
|
* @param {Partial<UpdateOptions>} options - additional options to control
|
|
160
178
|
* the update behavior
|
|
161
179
|
*/
|
|
162
|
-
|
|
180
|
+
abstract update(
|
|
163
181
|
updates: Map<string, string> | Record<string, string>,
|
|
164
182
|
options?: Partial<UpdateOptions>,
|
|
165
|
-
)
|
|
166
|
-
const onlyIf = options?.where;
|
|
167
|
-
let columns: [string, string][];
|
|
168
|
-
if (updates instanceof Map) {
|
|
169
|
-
columns = Array.from(updates.entries());
|
|
170
|
-
} else {
|
|
171
|
-
columns = Object.entries(updates);
|
|
172
|
-
}
|
|
173
|
-
await this.inner.update(onlyIf, columns);
|
|
174
|
-
}
|
|
183
|
+
): Promise<void>;
|
|
175
184
|
|
|
176
185
|
/** Count the total number of rows in the dataset. */
|
|
177
|
-
|
|
178
|
-
return await this.inner.countRows(filter);
|
|
179
|
-
}
|
|
180
|
-
|
|
186
|
+
abstract countRows(filter?: string): Promise<number>;
|
|
181
187
|
/** Delete the rows that satisfy the predicate. */
|
|
182
|
-
|
|
183
|
-
await this.inner.delete(predicate);
|
|
184
|
-
}
|
|
185
|
-
|
|
188
|
+
abstract delete(predicate: string): Promise<void>;
|
|
186
189
|
/**
|
|
187
190
|
* Create an index to speed up queries.
|
|
188
191
|
*
|
|
@@ -190,6 +193,9 @@ export class Table {
|
|
|
190
193
|
* Indices on vector columns will speed up vector searches.
|
|
191
194
|
* Indices on scalar columns will speed up filtering (in both
|
|
192
195
|
* vector and non-vector searches)
|
|
196
|
+
*
|
|
197
|
+
* @note We currently don't support custom named indexes,
|
|
198
|
+
* The index name will always be `${column}_idx`
|
|
193
199
|
* @example
|
|
194
200
|
* // If the column has a vector (fixed size list) data type then
|
|
195
201
|
* // an IvfPq vector index will be created.
|
|
@@ -209,13 +215,10 @@ export class Table {
|
|
|
209
215
|
* // Or create a Scalar index
|
|
210
216
|
* await table.createIndex("my_float_col");
|
|
211
217
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
await this.inner.createIndex(nativeIndex, column, options?.replace);
|
|
217
|
-
}
|
|
218
|
-
|
|
218
|
+
abstract createIndex(
|
|
219
|
+
column: string,
|
|
220
|
+
options?: Partial<IndexOptions>,
|
|
221
|
+
): Promise<void>;
|
|
219
222
|
/**
|
|
220
223
|
* Create a {@link Query} Builder.
|
|
221
224
|
*
|
|
@@ -266,10 +269,20 @@ export class Table {
|
|
|
266
269
|
* }
|
|
267
270
|
* @returns {Query} A builder that can be used to parameterize the query
|
|
268
271
|
*/
|
|
269
|
-
query(): Query
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
abstract query(): Query;
|
|
273
|
+
/**
|
|
274
|
+
* Create a search query to find the nearest neighbors
|
|
275
|
+
* of the given query vector
|
|
276
|
+
* @param {string} query - the query. This will be converted to a vector using the table's provided embedding function
|
|
277
|
+
* @note If no embedding functions are defined in the table, this will error when collecting the results.
|
|
278
|
+
*/
|
|
279
|
+
abstract search(query: string): VectorQuery;
|
|
280
|
+
/**
|
|
281
|
+
* Create a search query to find the nearest neighbors
|
|
282
|
+
* of the given query vector
|
|
283
|
+
* @param {IntoVector} query - the query vector
|
|
284
|
+
*/
|
|
285
|
+
abstract search(query: IntoVector): VectorQuery;
|
|
273
286
|
/**
|
|
274
287
|
* Search the table with a given query vector.
|
|
275
288
|
*
|
|
@@ -277,11 +290,7 @@ export class Table {
|
|
|
277
290
|
* is the same thing as calling `nearestTo` on the builder returned
|
|
278
291
|
* by `query`. @see {@link Query#nearestTo} for more details.
|
|
279
292
|
*/
|
|
280
|
-
vectorSearch(vector:
|
|
281
|
-
return this.query().nearestTo(vector);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// TODO: Support BatchUDF
|
|
293
|
+
abstract vectorSearch(vector: IntoVector): VectorQuery;
|
|
285
294
|
/**
|
|
286
295
|
* Add new columns with defined values.
|
|
287
296
|
* @param {AddColumnsSql[]} newColumnTransforms pairs of column names and
|
|
@@ -289,19 +298,14 @@ export class Table {
|
|
|
289
298
|
* expressions will be evaluated for each row in the table, and can
|
|
290
299
|
* reference existing columns in the table.
|
|
291
300
|
*/
|
|
292
|
-
|
|
293
|
-
await this.inner.addColumns(newColumnTransforms);
|
|
294
|
-
}
|
|
301
|
+
abstract addColumns(newColumnTransforms: AddColumnsSql[]): Promise<void>;
|
|
295
302
|
|
|
296
303
|
/**
|
|
297
304
|
* Alter the name or nullability of columns.
|
|
298
305
|
* @param {ColumnAlteration[]} columnAlterations One or more alterations to
|
|
299
306
|
* apply to columns.
|
|
300
307
|
*/
|
|
301
|
-
|
|
302
|
-
await this.inner.alterColumns(columnAlterations);
|
|
303
|
-
}
|
|
304
|
-
|
|
308
|
+
abstract alterColumns(columnAlterations: ColumnAlteration[]): Promise<void>;
|
|
305
309
|
/**
|
|
306
310
|
* Drop one or more columns from the dataset
|
|
307
311
|
*
|
|
@@ -313,15 +317,10 @@ export class Table {
|
|
|
313
317
|
* be nested column references (e.g. "a.b.c") or top-level column names
|
|
314
318
|
* (e.g. "a").
|
|
315
319
|
*/
|
|
316
|
-
|
|
317
|
-
await this.inner.dropColumns(columnNames);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
+
abstract dropColumns(columnNames: string[]): Promise<void>;
|
|
320
321
|
/** Retrieve the version of the table */
|
|
321
|
-
async version(): Promise<number> {
|
|
322
|
-
return await this.inner.version();
|
|
323
|
-
}
|
|
324
322
|
|
|
323
|
+
abstract version(): Promise<number>;
|
|
325
324
|
/**
|
|
326
325
|
* Checks out a specific version of the table _This is an in-place operation._
|
|
327
326
|
*
|
|
@@ -347,19 +346,14 @@ export class Table {
|
|
|
347
346
|
* console.log(await table.version()); // 2
|
|
348
347
|
* ```
|
|
349
348
|
*/
|
|
350
|
-
|
|
351
|
-
await this.inner.checkout(version);
|
|
352
|
-
}
|
|
353
|
-
|
|
349
|
+
abstract checkout(version: number): Promise<void>;
|
|
354
350
|
/**
|
|
355
351
|
* Checkout the latest version of the table. _This is an in-place operation._
|
|
356
352
|
*
|
|
357
353
|
* The table will be set back into standard mode, and will track the latest
|
|
358
354
|
* version of the table.
|
|
359
355
|
*/
|
|
360
|
-
|
|
361
|
-
await this.inner.checkoutLatest();
|
|
362
|
-
}
|
|
356
|
+
abstract checkoutLatest(): Promise<void>;
|
|
363
357
|
|
|
364
358
|
/**
|
|
365
359
|
* Restore the table to the currently checked out version
|
|
@@ -373,10 +367,7 @@ export class Table {
|
|
|
373
367
|
* Once the operation concludes the table will no longer be in a checked
|
|
374
368
|
* out state and the read_consistency_interval, if any, will apply.
|
|
375
369
|
*/
|
|
376
|
-
|
|
377
|
-
await this.inner.restore();
|
|
378
|
-
}
|
|
379
|
-
|
|
370
|
+
abstract restore(): Promise<void>;
|
|
380
371
|
/**
|
|
381
372
|
* Optimize the on-disk data and indices for better performance.
|
|
382
373
|
*
|
|
@@ -407,6 +398,243 @@ export class Table {
|
|
|
407
398
|
* you have added or modified 100,000 or more records or run more than 20 data
|
|
408
399
|
* modification operations.
|
|
409
400
|
*/
|
|
401
|
+
abstract optimize(options?: Partial<OptimizeOptions>): Promise<OptimizeStats>;
|
|
402
|
+
/** List all indices that have been created with {@link Table.createIndex} */
|
|
403
|
+
abstract listIndices(): Promise<IndexConfig[]>;
|
|
404
|
+
/** Return the table as an arrow table */
|
|
405
|
+
abstract toArrow(): Promise<ArrowTable>;
|
|
406
|
+
|
|
407
|
+
abstract mergeInsert(on: string | string[]): MergeInsertBuilder;
|
|
408
|
+
|
|
409
|
+
/** List all the stats of a specified index
|
|
410
|
+
*
|
|
411
|
+
* @param {string} name The name of the index.
|
|
412
|
+
* @returns {IndexStatistics | undefined} The stats of the index. If the index does not exist, it will return undefined
|
|
413
|
+
*/
|
|
414
|
+
abstract indexStats(name: string): Promise<IndexStatistics | undefined>;
|
|
415
|
+
|
|
416
|
+
static async parseTableData(
|
|
417
|
+
data: Record<string, unknown>[] | TableLike,
|
|
418
|
+
options?: Partial<CreateTableOptions>,
|
|
419
|
+
streaming = false,
|
|
420
|
+
) {
|
|
421
|
+
let mode: string = options?.mode ?? "create";
|
|
422
|
+
const existOk = options?.existOk ?? false;
|
|
423
|
+
|
|
424
|
+
if (mode === "create" && existOk) {
|
|
425
|
+
mode = "exist_ok";
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let table: ArrowTable;
|
|
429
|
+
if (isArrowTable(data)) {
|
|
430
|
+
table = sanitizeTable(data);
|
|
431
|
+
} else {
|
|
432
|
+
table = makeArrowTable(data as Record<string, unknown>[], options);
|
|
433
|
+
}
|
|
434
|
+
if (streaming) {
|
|
435
|
+
const buf = await fromTableToStreamBuffer(
|
|
436
|
+
table,
|
|
437
|
+
options?.embeddingFunction,
|
|
438
|
+
options?.schema,
|
|
439
|
+
);
|
|
440
|
+
return { buf, mode };
|
|
441
|
+
} else {
|
|
442
|
+
const buf = await fromTableToBuffer(
|
|
443
|
+
table,
|
|
444
|
+
options?.embeddingFunction,
|
|
445
|
+
options?.schema,
|
|
446
|
+
);
|
|
447
|
+
return { buf, mode };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export class LocalTable extends Table {
|
|
453
|
+
private readonly inner: _NativeTable;
|
|
454
|
+
|
|
455
|
+
constructor(inner: _NativeTable) {
|
|
456
|
+
super();
|
|
457
|
+
this.inner = inner;
|
|
458
|
+
}
|
|
459
|
+
get name(): string {
|
|
460
|
+
return this.inner.name;
|
|
461
|
+
}
|
|
462
|
+
isOpen(): boolean {
|
|
463
|
+
return this.inner.isOpen();
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
close(): void {
|
|
467
|
+
this.inner.close();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
display(): string {
|
|
471
|
+
return this.inner.display();
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
private async getEmbeddingFunctions(): Promise<
|
|
475
|
+
Map<string, EmbeddingFunctionConfig>
|
|
476
|
+
> {
|
|
477
|
+
const schema = await this.schema();
|
|
478
|
+
const registry = getRegistry();
|
|
479
|
+
return registry.parseFunctions(schema.metadata);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/** Get the schema of the table. */
|
|
483
|
+
async schema(): Promise<Schema> {
|
|
484
|
+
const schemaBuf = await this.inner.schema();
|
|
485
|
+
const tbl = tableFromIPC(schemaBuf);
|
|
486
|
+
return tbl.schema;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
async add(data: Data, options?: Partial<AddDataOptions>): Promise<void> {
|
|
490
|
+
const mode = options?.mode ?? "append";
|
|
491
|
+
const schema = await this.schema();
|
|
492
|
+
const registry = getRegistry();
|
|
493
|
+
const functions = registry.parseFunctions(schema.metadata);
|
|
494
|
+
|
|
495
|
+
const buffer = await fromDataToBuffer(
|
|
496
|
+
data,
|
|
497
|
+
functions.values().next().value,
|
|
498
|
+
schema,
|
|
499
|
+
);
|
|
500
|
+
await this.inner.add(buffer, mode);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async update(
|
|
504
|
+
optsOrUpdates:
|
|
505
|
+
| (Map<string, string> | Record<string, string>)
|
|
506
|
+
| ({
|
|
507
|
+
values: Map<string, IntoSql> | Record<string, IntoSql>;
|
|
508
|
+
} & Partial<UpdateOptions>)
|
|
509
|
+
| ({
|
|
510
|
+
valuesSql: Map<string, string> | Record<string, string>;
|
|
511
|
+
} & Partial<UpdateOptions>),
|
|
512
|
+
options?: Partial<UpdateOptions>,
|
|
513
|
+
) {
|
|
514
|
+
const isValues =
|
|
515
|
+
"values" in optsOrUpdates && typeof optsOrUpdates.values !== "string";
|
|
516
|
+
const isValuesSql =
|
|
517
|
+
"valuesSql" in optsOrUpdates &&
|
|
518
|
+
typeof optsOrUpdates.valuesSql !== "string";
|
|
519
|
+
const isMap = (obj: unknown): obj is Map<string, string> => {
|
|
520
|
+
return obj instanceof Map;
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
let predicate;
|
|
524
|
+
let columns: [string, string][];
|
|
525
|
+
switch (true) {
|
|
526
|
+
case isMap(optsOrUpdates):
|
|
527
|
+
columns = Array.from(optsOrUpdates.entries());
|
|
528
|
+
predicate = options?.where;
|
|
529
|
+
break;
|
|
530
|
+
case isValues && isMap(optsOrUpdates.values):
|
|
531
|
+
columns = Array.from(optsOrUpdates.values.entries()).map(([k, v]) => [
|
|
532
|
+
k,
|
|
533
|
+
toSQL(v),
|
|
534
|
+
]);
|
|
535
|
+
predicate = optsOrUpdates.where;
|
|
536
|
+
break;
|
|
537
|
+
case isValues && !isMap(optsOrUpdates.values):
|
|
538
|
+
columns = Object.entries(optsOrUpdates.values).map(([k, v]) => [
|
|
539
|
+
k,
|
|
540
|
+
toSQL(v),
|
|
541
|
+
]);
|
|
542
|
+
predicate = optsOrUpdates.where;
|
|
543
|
+
break;
|
|
544
|
+
|
|
545
|
+
case isValuesSql && isMap(optsOrUpdates.valuesSql):
|
|
546
|
+
columns = Array.from(optsOrUpdates.valuesSql.entries());
|
|
547
|
+
predicate = optsOrUpdates.where;
|
|
548
|
+
break;
|
|
549
|
+
case isValuesSql && !isMap(optsOrUpdates.valuesSql):
|
|
550
|
+
columns = Object.entries(optsOrUpdates.valuesSql).map(([k, v]) => [
|
|
551
|
+
k,
|
|
552
|
+
v,
|
|
553
|
+
]);
|
|
554
|
+
predicate = optsOrUpdates.where;
|
|
555
|
+
break;
|
|
556
|
+
default:
|
|
557
|
+
columns = Object.entries(optsOrUpdates as Record<string, string>);
|
|
558
|
+
predicate = options?.where;
|
|
559
|
+
}
|
|
560
|
+
await this.inner.update(predicate, columns);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async countRows(filter?: string): Promise<number> {
|
|
564
|
+
return await this.inner.countRows(filter);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
async delete(predicate: string): Promise<void> {
|
|
568
|
+
await this.inner.delete(predicate);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
async createIndex(column: string, options?: Partial<IndexOptions>) {
|
|
572
|
+
// Bit of a hack to get around the fact that TS has no package-scope.
|
|
573
|
+
// biome-ignore lint/suspicious/noExplicitAny: skip
|
|
574
|
+
const nativeIndex = (options?.config as any)?.inner;
|
|
575
|
+
await this.inner.createIndex(nativeIndex, column, options?.replace);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
query(): Query {
|
|
579
|
+
return new Query(this.inner);
|
|
580
|
+
}
|
|
581
|
+
search(query: string | IntoVector): VectorQuery {
|
|
582
|
+
if (typeof query !== "string") {
|
|
583
|
+
return this.vectorSearch(query);
|
|
584
|
+
} else {
|
|
585
|
+
const queryPromise = this.getEmbeddingFunctions().then(
|
|
586
|
+
async (functions) => {
|
|
587
|
+
// TODO: Support multiple embedding functions
|
|
588
|
+
const embeddingFunc: EmbeddingFunctionConfig | undefined = functions
|
|
589
|
+
.values()
|
|
590
|
+
.next().value;
|
|
591
|
+
if (!embeddingFunc) {
|
|
592
|
+
return Promise.reject(
|
|
593
|
+
new Error("No embedding functions are defined in the table"),
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
return await embeddingFunc.function.computeQueryEmbeddings(query);
|
|
597
|
+
},
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
return this.query().nearestTo(queryPromise);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
vectorSearch(vector: IntoVector): VectorQuery {
|
|
605
|
+
return this.query().nearestTo(vector);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// TODO: Support BatchUDF
|
|
609
|
+
|
|
610
|
+
async addColumns(newColumnTransforms: AddColumnsSql[]): Promise<void> {
|
|
611
|
+
await this.inner.addColumns(newColumnTransforms);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
async alterColumns(columnAlterations: ColumnAlteration[]): Promise<void> {
|
|
615
|
+
await this.inner.alterColumns(columnAlterations);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
async dropColumns(columnNames: string[]): Promise<void> {
|
|
619
|
+
await this.inner.dropColumns(columnNames);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
async version(): Promise<number> {
|
|
623
|
+
return await this.inner.version();
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
async checkout(version: number): Promise<void> {
|
|
627
|
+
await this.inner.checkout(version);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
async checkoutLatest(): Promise<void> {
|
|
631
|
+
await this.inner.checkoutLatest();
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
async restore(): Promise<void> {
|
|
635
|
+
await this.inner.restore();
|
|
636
|
+
}
|
|
637
|
+
|
|
410
638
|
async optimize(options?: Partial<OptimizeOptions>): Promise<OptimizeStats> {
|
|
411
639
|
let cleanupOlderThanMs;
|
|
412
640
|
if (
|
|
@@ -419,8 +647,23 @@ export class Table {
|
|
|
419
647
|
return await this.inner.optimize(cleanupOlderThanMs);
|
|
420
648
|
}
|
|
421
649
|
|
|
422
|
-
/** List all indices that have been created with {@link Table.createIndex} */
|
|
423
650
|
async listIndices(): Promise<IndexConfig[]> {
|
|
424
651
|
return await this.inner.listIndices();
|
|
425
652
|
}
|
|
653
|
+
|
|
654
|
+
async toArrow(): Promise<ArrowTable> {
|
|
655
|
+
return await this.query().toArrow();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
async indexStats(name: string): Promise<IndexStatistics | undefined> {
|
|
659
|
+
const stats = await this.inner.indexStats(name);
|
|
660
|
+
if (stats === null) {
|
|
661
|
+
return undefined;
|
|
662
|
+
}
|
|
663
|
+
return stats;
|
|
664
|
+
}
|
|
665
|
+
mergeInsert(on: string | string[]): MergeInsertBuilder {
|
|
666
|
+
on = Array.isArray(on) ? on : [on];
|
|
667
|
+
return new MergeInsertBuilder(this.inner.mergeInsert(on));
|
|
668
|
+
}
|
|
426
669
|
}
|
package/lancedb/util.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export type IntoSql =
|
|
2
|
+
| string
|
|
3
|
+
| number
|
|
4
|
+
| boolean
|
|
5
|
+
| null
|
|
6
|
+
| Date
|
|
7
|
+
| ArrayBufferLike
|
|
8
|
+
| Buffer
|
|
9
|
+
| IntoSql[];
|
|
10
|
+
|
|
11
|
+
export function toSQL(value: IntoSql): string {
|
|
12
|
+
if (typeof value === "string") {
|
|
13
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
14
|
+
} else if (typeof value === "number") {
|
|
15
|
+
return value.toString();
|
|
16
|
+
} else if (typeof value === "boolean") {
|
|
17
|
+
return value ? "TRUE" : "FALSE";
|
|
18
|
+
} else if (value === null) {
|
|
19
|
+
return "NULL";
|
|
20
|
+
} else if (value instanceof Date) {
|
|
21
|
+
return `'${value.toISOString()}'`;
|
|
22
|
+
} else if (Array.isArray(value)) {
|
|
23
|
+
return `[${value.map(toSQL).join(", ")}]`;
|
|
24
|
+
} else if (Buffer.isBuffer(value)) {
|
|
25
|
+
return `X'${value.toString("hex")}'`;
|
|
26
|
+
} else if (value instanceof ArrayBuffer) {
|
|
27
|
+
return `X'${Buffer.from(value).toString("hex")}'`;
|
|
28
|
+
} else {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Unsupported value type: ${typeof value} value: (${value})`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class TTLCache {
|
|
36
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
37
|
+
private readonly cache: Map<string, { value: any; expires: number }>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param ttl Time to live in milliseconds
|
|
41
|
+
*/
|
|
42
|
+
constructor(private readonly ttl: number) {
|
|
43
|
+
this.cache = new Map();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
47
|
+
get(key: string): any | undefined {
|
|
48
|
+
const entry = this.cache.get(key);
|
|
49
|
+
if (entry === undefined) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (entry.expires < Date.now()) {
|
|
54
|
+
this.cache.delete(key);
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return entry.value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
62
|
+
set(key: string, value: any): void {
|
|
63
|
+
this.cache.set(key, { value, expires: Date.now() + this.ttl });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
delete(key: string): void {
|
|
67
|
+
this.cache.delete(key);
|
|
68
|
+
}
|
|
69
|
+
}
|