@anvailabs/proximadb-client 0.3.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/README.md +160 -0
- package/dist/client.d.ts +319 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +681 -0
- package/dist/client.js.map +1 -0
- package/dist/collection.d.ts +227 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +436 -0
- package/dist/collection.js.map +1 -0
- package/dist/esm/client.js +674 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/collection.js +428 -0
- package/dist/esm/collection.js.map +1 -0
- package/dist/esm/filter.js +228 -0
- package/dist/esm/filter.js.map +1 -0
- package/dist/esm/generated/schema.js +6 -0
- package/dist/esm/generated/schema.js.map +1 -0
- package/dist/esm/graph.js +678 -0
- package/dist/esm/graph.js.map +1 -0
- package/dist/esm/index.js +86 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/search.js +317 -0
- package/dist/esm/search.js.map +1 -0
- package/dist/esm/transport.js +33 -0
- package/dist/esm/transport.js.map +1 -0
- package/dist/esm/types.js +181 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/filter.d.ts +51 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +241 -0
- package/dist/filter.js.map +1 -0
- package/dist/generated/schema.d.ts +4271 -0
- package/dist/generated/schema.d.ts.map +1 -0
- package/dist/generated/schema.js +7 -0
- package/dist/generated/schema.js.map +1 -0
- package/dist/graph.d.ts +350 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +690 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/dist/search.d.ts +160 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +322 -0
- package/dist/search.js.map +1 -0
- package/dist/transport.d.ts +40 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +39 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +632 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +185 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
- package/src/client.ts +856 -0
- package/src/collection.ts +578 -0
- package/src/filter.ts +280 -0
- package/src/generated/schema.ts +4271 -0
- package/src/graph.ts +811 -0
- package/src/index.ts +184 -0
- package/src/search.ts +401 -0
- package/src/transport.ts +52 -0
- package/src/types.ts +726 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProximaDB TypeScript SDK - Collection Management
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent API for collection CRUD operations and search.
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2025 ProximaDB Contributors
|
|
7
|
+
* Licensed under the Apache License, Version 2.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
CollectionConfig,
|
|
12
|
+
CollectionInfo,
|
|
13
|
+
ProximaRecord,
|
|
14
|
+
VectorRecord,
|
|
15
|
+
SearchResult,
|
|
16
|
+
JsonValue,
|
|
17
|
+
} from "./types";
|
|
18
|
+
import {
|
|
19
|
+
DistanceMetric,
|
|
20
|
+
StorageEngine,
|
|
21
|
+
IndexType,
|
|
22
|
+
} from "./types";
|
|
23
|
+
import { SearchBuilder, SearchHttpClient } from "./search";
|
|
24
|
+
|
|
25
|
+
type RecordBatchResponse = {
|
|
26
|
+
inserted_count?: number;
|
|
27
|
+
success_count?: number;
|
|
28
|
+
success?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function recordPayload(record: {
|
|
32
|
+
id: string;
|
|
33
|
+
vector?: number[];
|
|
34
|
+
metadata?: Record<string, JsonValue>;
|
|
35
|
+
props?: Record<string, JsonValue>;
|
|
36
|
+
source?: string;
|
|
37
|
+
}): ProximaRecord {
|
|
38
|
+
return {
|
|
39
|
+
id: record.id,
|
|
40
|
+
vector: record.vector ?? [],
|
|
41
|
+
props: record.props ?? record.metadata ?? {},
|
|
42
|
+
source: record.source,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function insertedCount(response: RecordBatchResponse): number {
|
|
47
|
+
return response.success_count ?? response.inserted_count ?? response.success ?? 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* HTTP client interface for collection operations
|
|
52
|
+
*/
|
|
53
|
+
export interface CollectionHttpClient extends SearchHttpClient {
|
|
54
|
+
get<T>(url: string): Promise<T>;
|
|
55
|
+
delete<T>(url: string): Promise<T>;
|
|
56
|
+
/**
|
|
57
|
+
* Typed transport for core collection / record ops (TD-126 Phase 4). These
|
|
58
|
+
* route through the generated REST client (src/generated/schema.ts) instead
|
|
59
|
+
* of hand-built URL strings.
|
|
60
|
+
*/
|
|
61
|
+
createCollectionRequest(body: Record<string, unknown>): Promise<unknown>;
|
|
62
|
+
getCollectionRequest(collectionId: string): Promise<unknown>;
|
|
63
|
+
insertRecordsRequest(
|
|
64
|
+
collectionId: string,
|
|
65
|
+
body: Record<string, unknown>,
|
|
66
|
+
): Promise<unknown>;
|
|
67
|
+
getRecordRequest(
|
|
68
|
+
collectionId: string,
|
|
69
|
+
recordId: string,
|
|
70
|
+
includeVector: boolean,
|
|
71
|
+
includeText: boolean,
|
|
72
|
+
): Promise<unknown>;
|
|
73
|
+
deleteRecordRequest(collectionId: string, recordId: string): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// COLLECTION BUILDER
|
|
78
|
+
// ============================================================================
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Builder for creating collections
|
|
82
|
+
*/
|
|
83
|
+
export class CollectionBuilder {
|
|
84
|
+
private client: CollectionHttpClient;
|
|
85
|
+
private collectionName: string;
|
|
86
|
+
private dimensionValue: number | null = null;
|
|
87
|
+
private engineValue: StorageEngine = StorageEngine.Sst;
|
|
88
|
+
private indexValue: IndexType = IndexType.Hnsw;
|
|
89
|
+
private metricValue: DistanceMetric = DistanceMetric.Cosine;
|
|
90
|
+
private descriptionValue: string | null = null;
|
|
91
|
+
private tagsValue: string[] = [];
|
|
92
|
+
|
|
93
|
+
constructor(client: CollectionHttpClient, name: string) {
|
|
94
|
+
this.client = client;
|
|
95
|
+
this.collectionName = name;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Set the vector dimension (required)
|
|
100
|
+
*/
|
|
101
|
+
dimension(dim: number): CollectionBuilder {
|
|
102
|
+
this.dimensionValue = dim;
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Set the storage engine
|
|
108
|
+
*/
|
|
109
|
+
engine(eng: StorageEngine): CollectionBuilder {
|
|
110
|
+
this.engineValue = eng;
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Set the storage engine from string
|
|
116
|
+
*/
|
|
117
|
+
engineStr(eng: string): CollectionBuilder {
|
|
118
|
+
this.engineValue = eng as StorageEngine;
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Set the index type
|
|
124
|
+
*/
|
|
125
|
+
index(idx: IndexType): CollectionBuilder {
|
|
126
|
+
this.indexValue = idx;
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Set the distance metric
|
|
132
|
+
*/
|
|
133
|
+
metric(met: DistanceMetric): CollectionBuilder {
|
|
134
|
+
this.metricValue = met;
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Set the collection description
|
|
140
|
+
*/
|
|
141
|
+
description(desc: string): CollectionBuilder {
|
|
142
|
+
this.descriptionValue = desc;
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Add tags to the collection
|
|
148
|
+
*/
|
|
149
|
+
tags(tagList: string[]): CollectionBuilder {
|
|
150
|
+
this.tagsValue = tagList;
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Execute the collection creation
|
|
156
|
+
*/
|
|
157
|
+
async execute(): Promise<void> {
|
|
158
|
+
if (this.dimensionValue === null) {
|
|
159
|
+
throw new Error("Dimension is required for collection creation");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const request = {
|
|
163
|
+
name: this.collectionName,
|
|
164
|
+
dimension: this.dimensionValue,
|
|
165
|
+
engine: this.engineValue,
|
|
166
|
+
index_type: this.indexValue,
|
|
167
|
+
distance_metric: this.metricValue,
|
|
168
|
+
description: this.descriptionValue ?? undefined,
|
|
169
|
+
tags: this.tagsValue.length > 0 ? this.tagsValue : undefined,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
await this.client.createCollectionRequest(request as Record<string, unknown>);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Build the configuration without executing
|
|
177
|
+
*/
|
|
178
|
+
build(): CollectionConfig {
|
|
179
|
+
if (this.dimensionValue === null) {
|
|
180
|
+
throw new Error("Dimension is required");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
name: this.collectionName,
|
|
185
|
+
dimension: this.dimensionValue,
|
|
186
|
+
distanceMetric: this.metricValue,
|
|
187
|
+
storageEngine: this.engineValue,
|
|
188
|
+
indexType: this.indexValue,
|
|
189
|
+
description: this.descriptionValue ?? undefined,
|
|
190
|
+
tags: this.tagsValue.length > 0 ? this.tagsValue : undefined,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// INSERT BUILDER
|
|
197
|
+
// ============================================================================
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Builder for insert operations
|
|
201
|
+
*/
|
|
202
|
+
export class InsertBuilder {
|
|
203
|
+
private client: CollectionHttpClient;
|
|
204
|
+
private collectionName: string;
|
|
205
|
+
private currentId: string | null = null;
|
|
206
|
+
private currentVector: number[] | null = null;
|
|
207
|
+
private currentMetadata: Record<string, JsonValue> = {};
|
|
208
|
+
|
|
209
|
+
constructor(client: CollectionHttpClient, collection: string) {
|
|
210
|
+
this.client = client;
|
|
211
|
+
this.collectionName = collection;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Set the vector ID
|
|
216
|
+
*/
|
|
217
|
+
id(vectorId: string): InsertBuilder {
|
|
218
|
+
this.currentId = vectorId;
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Set the vector data
|
|
224
|
+
*/
|
|
225
|
+
vector(vec: number[]): InsertBuilder {
|
|
226
|
+
this.currentVector = vec;
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Set metadata from object
|
|
232
|
+
*/
|
|
233
|
+
metadata(meta: Record<string, JsonValue>): InsertBuilder {
|
|
234
|
+
Object.assign(this.currentMetadata, meta);
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Set a single metadata field
|
|
240
|
+
*/
|
|
241
|
+
meta(key: string, value: JsonValue): InsertBuilder {
|
|
242
|
+
this.currentMetadata[key] = value;
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Execute single vector insert
|
|
248
|
+
*/
|
|
249
|
+
async execute(): Promise<void> {
|
|
250
|
+
if (this.currentId === null) {
|
|
251
|
+
throw new Error("Vector ID is required");
|
|
252
|
+
}
|
|
253
|
+
if (this.currentVector === null) {
|
|
254
|
+
throw new Error("Vector data is required");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const record = {
|
|
258
|
+
id: this.currentId,
|
|
259
|
+
vector: this.currentVector,
|
|
260
|
+
props: this.currentMetadata,
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const request = {
|
|
264
|
+
records: [record],
|
|
265
|
+
validate_schema: true,
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
await this.client.insertRecordsRequest(
|
|
269
|
+
this.collectionName,
|
|
270
|
+
request as unknown as Record<string, unknown>,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Builder for batch insert operations
|
|
277
|
+
*/
|
|
278
|
+
export class BatchInsertBuilder {
|
|
279
|
+
private client: CollectionHttpClient;
|
|
280
|
+
private collectionName: string;
|
|
281
|
+
private records: Array<{
|
|
282
|
+
id: string;
|
|
283
|
+
vector: number[];
|
|
284
|
+
metadata: Record<string, JsonValue>;
|
|
285
|
+
}> = [];
|
|
286
|
+
|
|
287
|
+
constructor(
|
|
288
|
+
client: CollectionHttpClient,
|
|
289
|
+
collection: string,
|
|
290
|
+
ids: string[],
|
|
291
|
+
vectors: number[][]
|
|
292
|
+
) {
|
|
293
|
+
this.client = client;
|
|
294
|
+
this.collectionName = collection;
|
|
295
|
+
|
|
296
|
+
if (ids.length !== vectors.length) {
|
|
297
|
+
throw new Error("IDs and vectors arrays must have the same length");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
for (let i = 0; i < ids.length; i++) {
|
|
301
|
+
this.records.push({
|
|
302
|
+
id: ids[i]!,
|
|
303
|
+
vector: vectors[i]!,
|
|
304
|
+
metadata: {},
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Add metadata for all vectors
|
|
311
|
+
*/
|
|
312
|
+
withMetadata(metadataList: Array<Record<string, JsonValue>>): BatchInsertBuilder {
|
|
313
|
+
if (metadataList.length !== this.records.length) {
|
|
314
|
+
throw new Error("Metadata array must match the number of vectors");
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
for (let i = 0; i < metadataList.length; i++) {
|
|
318
|
+
this.records[i]!.metadata = metadataList[i]!;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return this;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Execute the batch insert
|
|
326
|
+
*/
|
|
327
|
+
async execute(): Promise<number> {
|
|
328
|
+
const request = {
|
|
329
|
+
records: this.records.map(recordPayload),
|
|
330
|
+
validate_schema: true,
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const response = (await this.client.insertRecordsRequest(
|
|
334
|
+
this.collectionName,
|
|
335
|
+
request as unknown as Record<string, unknown>,
|
|
336
|
+
)) as RecordBatchResponse;
|
|
337
|
+
return insertedCount(response);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// ============================================================================
|
|
342
|
+
// UPDATE BUILDER
|
|
343
|
+
// ============================================================================
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Builder for update operations
|
|
347
|
+
*/
|
|
348
|
+
export class UpdateBuilder {
|
|
349
|
+
private client: CollectionHttpClient;
|
|
350
|
+
private collectionName: string;
|
|
351
|
+
private vectorId: string;
|
|
352
|
+
private newVector: number[] | null = null;
|
|
353
|
+
private newMetadata: Record<string, JsonValue> = {};
|
|
354
|
+
private replaceMetadataFlag: boolean = false;
|
|
355
|
+
|
|
356
|
+
constructor(client: CollectionHttpClient, collection: string, id: string) {
|
|
357
|
+
this.client = client;
|
|
358
|
+
this.collectionName = collection;
|
|
359
|
+
this.vectorId = id;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Set a new vector
|
|
364
|
+
*/
|
|
365
|
+
vector(vec: number[]): UpdateBuilder {
|
|
366
|
+
this.newVector = vec;
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Set metadata from object (merges with existing)
|
|
372
|
+
*/
|
|
373
|
+
metadata(meta: Record<string, JsonValue>): UpdateBuilder {
|
|
374
|
+
Object.assign(this.newMetadata, meta);
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Set a single metadata field
|
|
380
|
+
*/
|
|
381
|
+
meta(key: string, value: JsonValue): UpdateBuilder {
|
|
382
|
+
this.newMetadata[key] = value;
|
|
383
|
+
return this;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Replace all metadata instead of merging
|
|
388
|
+
*/
|
|
389
|
+
replaceMetadata(replace: boolean = true): UpdateBuilder {
|
|
390
|
+
this.replaceMetadataFlag = replace;
|
|
391
|
+
return this;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Execute the update
|
|
396
|
+
*/
|
|
397
|
+
async execute(): Promise<void> {
|
|
398
|
+
const request = {
|
|
399
|
+
records: [{
|
|
400
|
+
id: this.vectorId,
|
|
401
|
+
vector: this.newVector ?? [],
|
|
402
|
+
props: Object.keys(this.newMetadata).length > 0 ? this.newMetadata : undefined,
|
|
403
|
+
}],
|
|
404
|
+
validate_schema: true,
|
|
405
|
+
upsert: true,
|
|
406
|
+
replace_metadata: this.replaceMetadataFlag,
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
await this.client.insertRecordsRequest(
|
|
410
|
+
this.collectionName,
|
|
411
|
+
request as unknown as Record<string, unknown>,
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ============================================================================
|
|
417
|
+
// COLLECTION HANDLE
|
|
418
|
+
// ============================================================================
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Handle to a collection for fluent operations
|
|
422
|
+
*/
|
|
423
|
+
export class CollectionHandle {
|
|
424
|
+
private client: CollectionHttpClient;
|
|
425
|
+
private collectionName: string;
|
|
426
|
+
|
|
427
|
+
constructor(client: CollectionHttpClient, name: string) {
|
|
428
|
+
this.client = client;
|
|
429
|
+
this.collectionName = name;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Get the collection name
|
|
434
|
+
*/
|
|
435
|
+
getName(): string {
|
|
436
|
+
return this.collectionName;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Start building a search query
|
|
441
|
+
*/
|
|
442
|
+
search(): SearchBuilder {
|
|
443
|
+
return new SearchBuilder(this.client, this.collectionName);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Start building an insert operation
|
|
448
|
+
*/
|
|
449
|
+
insert(): InsertBuilder {
|
|
450
|
+
return new InsertBuilder(this.client, this.collectionName);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Start building a batch insert operation
|
|
455
|
+
*/
|
|
456
|
+
batch(ids: string[], vectors: number[][]): BatchInsertBuilder {
|
|
457
|
+
return new BatchInsertBuilder(this.client, this.collectionName, ids, vectors);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Start building an update operation for a vector
|
|
462
|
+
*/
|
|
463
|
+
update(id: string): UpdateBuilder {
|
|
464
|
+
return new UpdateBuilder(this.client, this.collectionName, id);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Get collection information
|
|
469
|
+
*/
|
|
470
|
+
async info(): Promise<CollectionInfo> {
|
|
471
|
+
return (await this.client.getCollectionRequest(
|
|
472
|
+
this.collectionName,
|
|
473
|
+
)) as CollectionInfo;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Get vector count
|
|
478
|
+
*/
|
|
479
|
+
async count(): Promise<number> {
|
|
480
|
+
const info = await this.info();
|
|
481
|
+
return info.vectorCount ?? 0;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Delete the collection
|
|
486
|
+
*/
|
|
487
|
+
async delete(): Promise<void> {
|
|
488
|
+
const url = this.client.url() + "/api/v2/collections/" + this.collectionName;
|
|
489
|
+
await this.client.delete<unknown>(url);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Get a vector by ID
|
|
494
|
+
*/
|
|
495
|
+
async getVector(id: string): Promise<VectorRecord | null> {
|
|
496
|
+
try {
|
|
497
|
+
return (await this.client.getRecordRequest(
|
|
498
|
+
this.collectionName,
|
|
499
|
+
id,
|
|
500
|
+
true,
|
|
501
|
+
false,
|
|
502
|
+
)) as VectorRecord;
|
|
503
|
+
} catch (e: unknown) {
|
|
504
|
+
if (e instanceof Error && e.message.includes("404")) {
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
throw e;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Check if a vector exists
|
|
513
|
+
*/
|
|
514
|
+
async exists(id: string): Promise<boolean> {
|
|
515
|
+
const vector = await this.getVector(id);
|
|
516
|
+
return vector !== null;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Delete a vector by ID
|
|
521
|
+
*/
|
|
522
|
+
async deleteVector(id: string): Promise<void> {
|
|
523
|
+
await this.client.deleteRecordRequest(this.collectionName, id);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Delete multiple vectors by IDs
|
|
528
|
+
*/
|
|
529
|
+
async deleteVectors(ids: string[]): Promise<number> {
|
|
530
|
+
await Promise.all(ids.map((id) => this.deleteVector(id)));
|
|
531
|
+
return ids.length;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Insert a single vector (convenience method)
|
|
536
|
+
*/
|
|
537
|
+
async insertVector(
|
|
538
|
+
id: string,
|
|
539
|
+
vector: number[],
|
|
540
|
+
metadata?: Record<string, JsonValue>
|
|
541
|
+
): Promise<void> {
|
|
542
|
+
const builder = this.insert().id(id).vector(vector);
|
|
543
|
+
if (metadata) {
|
|
544
|
+
builder.metadata(metadata);
|
|
545
|
+
}
|
|
546
|
+
await builder.execute();
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Insert multiple vectors (convenience method)
|
|
551
|
+
*/
|
|
552
|
+
async insertVectors(
|
|
553
|
+
ids: string[],
|
|
554
|
+
vectors: number[][],
|
|
555
|
+
metadata?: Array<Record<string, JsonValue>>
|
|
556
|
+
): Promise<number> {
|
|
557
|
+
const builder = this.batch(ids, vectors);
|
|
558
|
+
if (metadata) {
|
|
559
|
+
builder.withMetadata(metadata);
|
|
560
|
+
}
|
|
561
|
+
return await builder.execute();
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Search vectors (convenience method)
|
|
566
|
+
*/
|
|
567
|
+
async searchVectors(
|
|
568
|
+
queryVector: number[],
|
|
569
|
+
topK: number = 10,
|
|
570
|
+
filter?: string
|
|
571
|
+
): Promise<SearchResult[]> {
|
|
572
|
+
const builder = this.search().vector(queryVector).topK(topK);
|
|
573
|
+
if (filter) {
|
|
574
|
+
builder.filter(filter);
|
|
575
|
+
}
|
|
576
|
+
return await builder.execute();
|
|
577
|
+
}
|
|
578
|
+
}
|