@wiscale/velesdb-sdk 1.0.0 → 1.1.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/README.md +35 -0
- package/dist/index.d.mts +75 -3
- package/dist/index.d.ts +75 -3
- package/dist/index.js +96 -4
- package/dist/index.mjs +96 -4
- package/package.json +12 -9
package/README.md
CHANGED
|
@@ -188,6 +188,41 @@ const results = await db.query(
|
|
|
188
188
|
);
|
|
189
189
|
```
|
|
190
190
|
|
|
191
|
+
### `db.multiQuerySearch(collection, vectors, options)` (v1.1.0+) ⭐ NEW
|
|
192
|
+
|
|
193
|
+
Multi-query fusion search for RAG pipelines using Multiple Query Generation (MQG).
|
|
194
|
+
|
|
195
|
+
| Option | Type | Default | Description |
|
|
196
|
+
|--------|------|---------|-------------|
|
|
197
|
+
| `k` | `number` | `10` | Number of results |
|
|
198
|
+
| `fusion` | `'rrf' \| 'average' \| 'maximum' \| 'weighted'` | `'rrf'` | Fusion strategy |
|
|
199
|
+
| `fusionParams` | `object` | `{ k: 60 }` | Strategy-specific parameters |
|
|
200
|
+
| `filter` | `object` | - | Filter expression |
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// RRF fusion (default) - best for most RAG use cases
|
|
204
|
+
const results = await db.multiQuerySearch('docs', [emb1, emb2, emb3], {
|
|
205
|
+
k: 10,
|
|
206
|
+
fusion: 'rrf',
|
|
207
|
+
fusionParams: { k: 60 }
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Weighted fusion - like SearchXP scoring
|
|
211
|
+
const results = await db.multiQuerySearch('docs', [emb1, emb2], {
|
|
212
|
+
k: 10,
|
|
213
|
+
fusion: 'weighted',
|
|
214
|
+
fusionParams: { avgWeight: 0.6, maxWeight: 0.3, hitWeight: 0.1 }
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Average/Maximum fusion
|
|
218
|
+
const results = await db.multiQuerySearch('docs', vectors, {
|
|
219
|
+
k: 10,
|
|
220
|
+
fusion: 'average' // or 'maximum'
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
> **Note:** Multi-query fusion is only available with the REST backend.
|
|
225
|
+
|
|
191
226
|
### `db.isEmpty(collection)` (v0.8.11+)
|
|
192
227
|
|
|
193
228
|
Check if a collection is empty.
|
package/dist/index.d.mts
CHANGED
|
@@ -19,10 +19,12 @@ interface VelesDBConfig {
|
|
|
19
19
|
/** Request timeout in milliseconds (default: 30000) */
|
|
20
20
|
timeout?: number;
|
|
21
21
|
}
|
|
22
|
+
/** Collection type */
|
|
23
|
+
type CollectionType = 'vector' | 'metadata_only';
|
|
22
24
|
/** Collection configuration */
|
|
23
25
|
interface CollectionConfig {
|
|
24
|
-
/** Vector dimension (e.g., 768 for BERT, 1536 for GPT) */
|
|
25
|
-
dimension
|
|
26
|
+
/** Vector dimension (e.g., 768 for BERT, 1536 for GPT). Required for vector collections. */
|
|
27
|
+
dimension?: number;
|
|
26
28
|
/** Distance metric (default: 'cosine') */
|
|
27
29
|
metric?: DistanceMetric;
|
|
28
30
|
/** Storage mode for vector quantization (default: 'full')
|
|
@@ -31,6 +33,8 @@ interface CollectionConfig {
|
|
|
31
33
|
* - 'binary': 1-bit binary quantization, 32x memory reduction (edge/IoT)
|
|
32
34
|
*/
|
|
33
35
|
storageMode?: StorageMode;
|
|
36
|
+
/** Collection type: 'vector' (default) or 'metadata_only' */
|
|
37
|
+
collectionType?: CollectionType;
|
|
34
38
|
/** Optional collection description */
|
|
35
39
|
description?: string;
|
|
36
40
|
}
|
|
@@ -67,6 +71,28 @@ interface SearchOptions {
|
|
|
67
71
|
/** Include vectors in results (default: false) */
|
|
68
72
|
includeVectors?: boolean;
|
|
69
73
|
}
|
|
74
|
+
/** Fusion strategy for multi-query search */
|
|
75
|
+
type FusionStrategy = 'rrf' | 'average' | 'maximum' | 'weighted';
|
|
76
|
+
/** Multi-query search options */
|
|
77
|
+
interface MultiQuerySearchOptions {
|
|
78
|
+
/** Number of results to return (default: 10) */
|
|
79
|
+
k?: number;
|
|
80
|
+
/** Fusion strategy (default: 'rrf') */
|
|
81
|
+
fusion?: FusionStrategy;
|
|
82
|
+
/** Fusion parameters */
|
|
83
|
+
fusionParams?: {
|
|
84
|
+
/** RRF k parameter (default: 60) */
|
|
85
|
+
k?: number;
|
|
86
|
+
/** Weighted fusion: average weight (default: 0.6) */
|
|
87
|
+
avgWeight?: number;
|
|
88
|
+
/** Weighted fusion: max weight (default: 0.3) */
|
|
89
|
+
maxWeight?: number;
|
|
90
|
+
/** Weighted fusion: hit weight (default: 0.1) */
|
|
91
|
+
hitWeight?: number;
|
|
92
|
+
};
|
|
93
|
+
/** Filter expression (optional) */
|
|
94
|
+
filter?: Record<string, unknown>;
|
|
95
|
+
}
|
|
70
96
|
/** Search result */
|
|
71
97
|
interface SearchResult {
|
|
72
98
|
/** Document ID */
|
|
@@ -121,6 +147,8 @@ interface IVelesDBBackend {
|
|
|
121
147
|
}): Promise<SearchResult[]>;
|
|
122
148
|
/** Execute VelesQL query */
|
|
123
149
|
query(queryString: string, params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
150
|
+
/** Multi-query fusion search */
|
|
151
|
+
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
124
152
|
/** Check if collection is empty */
|
|
125
153
|
isEmpty(collection: string): Promise<boolean>;
|
|
126
154
|
/** Flush pending changes to disk */
|
|
@@ -195,6 +223,20 @@ declare class VelesDB {
|
|
|
195
223
|
* @param config - Collection configuration
|
|
196
224
|
*/
|
|
197
225
|
createCollection(name: string, config: CollectionConfig): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* Create a metadata-only collection (no vectors, just payload data)
|
|
228
|
+
*
|
|
229
|
+
* Useful for storing reference data that can be JOINed with vector collections.
|
|
230
|
+
*
|
|
231
|
+
* @param name - Collection name
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* await db.createMetadataCollection('products');
|
|
236
|
+
* await db.insertMetadata('products', { id: 'P001', name: 'Widget', price: 99 });
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
createMetadataCollection(name: string): Promise<void>;
|
|
198
240
|
/**
|
|
199
241
|
* Delete a collection
|
|
200
242
|
*
|
|
@@ -300,6 +342,34 @@ declare class VelesDB {
|
|
|
300
342
|
* @returns Query results
|
|
301
343
|
*/
|
|
302
344
|
query(queryString: string, params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
345
|
+
/**
|
|
346
|
+
* Multi-query fusion search combining results from multiple query vectors
|
|
347
|
+
*
|
|
348
|
+
* Ideal for RAG pipelines using Multiple Query Generation (MQG).
|
|
349
|
+
*
|
|
350
|
+
* @param collection - Collection name
|
|
351
|
+
* @param vectors - Array of query vectors
|
|
352
|
+
* @param options - Search options (k, fusion strategy, fusionParams, filter)
|
|
353
|
+
* @returns Fused search results
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```typescript
|
|
357
|
+
* // RRF fusion (default)
|
|
358
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2, emb3], {
|
|
359
|
+
* k: 10,
|
|
360
|
+
* fusion: 'rrf',
|
|
361
|
+
* fusionParams: { k: 60 }
|
|
362
|
+
* });
|
|
363
|
+
*
|
|
364
|
+
* // Weighted fusion
|
|
365
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2], {
|
|
366
|
+
* k: 10,
|
|
367
|
+
* fusion: 'weighted',
|
|
368
|
+
* fusionParams: { avgWeight: 0.6, maxWeight: 0.3, hitWeight: 0.1 }
|
|
369
|
+
* });
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
303
373
|
/**
|
|
304
374
|
* Check if a collection is empty
|
|
305
375
|
*
|
|
@@ -366,6 +436,7 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
366
436
|
filter?: Record<string, unknown>;
|
|
367
437
|
}): Promise<SearchResult[]>;
|
|
368
438
|
query(_queryString: string, _params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
439
|
+
multiQuerySearch(_collection: string, _vectors: Array<number[] | Float32Array>, _options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
369
440
|
isEmpty(collectionName: string): Promise<boolean>;
|
|
370
441
|
flush(collectionName: string): Promise<void>;
|
|
371
442
|
close(): Promise<void>;
|
|
@@ -417,9 +488,10 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
417
488
|
filter?: Record<string, unknown>;
|
|
418
489
|
}): Promise<SearchResult[]>;
|
|
419
490
|
query(queryString: string, params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
491
|
+
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
420
492
|
isEmpty(collection: string): Promise<boolean>;
|
|
421
493
|
flush(collection: string): Promise<void>;
|
|
422
494
|
close(): Promise<void>;
|
|
423
495
|
}
|
|
424
496
|
|
|
425
|
-
export { type BackendType, type Collection, type CollectionConfig, ConnectionError, type DistanceMetric, type IVelesDBBackend, NotFoundError, RestBackend, type SearchOptions, type SearchResult, type StorageMode, ValidationError, type VectorDocument, VelesDB, type VelesDBConfig, VelesDBError, WasmBackend };
|
|
497
|
+
export { type BackendType, type Collection, type CollectionConfig, type CollectionType, ConnectionError, type DistanceMetric, type FusionStrategy, type IVelesDBBackend, type MultiQuerySearchOptions, NotFoundError, RestBackend, type SearchOptions, type SearchResult, type StorageMode, ValidationError, type VectorDocument, VelesDB, type VelesDBConfig, VelesDBError, WasmBackend };
|
package/dist/index.d.ts
CHANGED
|
@@ -19,10 +19,12 @@ interface VelesDBConfig {
|
|
|
19
19
|
/** Request timeout in milliseconds (default: 30000) */
|
|
20
20
|
timeout?: number;
|
|
21
21
|
}
|
|
22
|
+
/** Collection type */
|
|
23
|
+
type CollectionType = 'vector' | 'metadata_only';
|
|
22
24
|
/** Collection configuration */
|
|
23
25
|
interface CollectionConfig {
|
|
24
|
-
/** Vector dimension (e.g., 768 for BERT, 1536 for GPT) */
|
|
25
|
-
dimension
|
|
26
|
+
/** Vector dimension (e.g., 768 for BERT, 1536 for GPT). Required for vector collections. */
|
|
27
|
+
dimension?: number;
|
|
26
28
|
/** Distance metric (default: 'cosine') */
|
|
27
29
|
metric?: DistanceMetric;
|
|
28
30
|
/** Storage mode for vector quantization (default: 'full')
|
|
@@ -31,6 +33,8 @@ interface CollectionConfig {
|
|
|
31
33
|
* - 'binary': 1-bit binary quantization, 32x memory reduction (edge/IoT)
|
|
32
34
|
*/
|
|
33
35
|
storageMode?: StorageMode;
|
|
36
|
+
/** Collection type: 'vector' (default) or 'metadata_only' */
|
|
37
|
+
collectionType?: CollectionType;
|
|
34
38
|
/** Optional collection description */
|
|
35
39
|
description?: string;
|
|
36
40
|
}
|
|
@@ -67,6 +71,28 @@ interface SearchOptions {
|
|
|
67
71
|
/** Include vectors in results (default: false) */
|
|
68
72
|
includeVectors?: boolean;
|
|
69
73
|
}
|
|
74
|
+
/** Fusion strategy for multi-query search */
|
|
75
|
+
type FusionStrategy = 'rrf' | 'average' | 'maximum' | 'weighted';
|
|
76
|
+
/** Multi-query search options */
|
|
77
|
+
interface MultiQuerySearchOptions {
|
|
78
|
+
/** Number of results to return (default: 10) */
|
|
79
|
+
k?: number;
|
|
80
|
+
/** Fusion strategy (default: 'rrf') */
|
|
81
|
+
fusion?: FusionStrategy;
|
|
82
|
+
/** Fusion parameters */
|
|
83
|
+
fusionParams?: {
|
|
84
|
+
/** RRF k parameter (default: 60) */
|
|
85
|
+
k?: number;
|
|
86
|
+
/** Weighted fusion: average weight (default: 0.6) */
|
|
87
|
+
avgWeight?: number;
|
|
88
|
+
/** Weighted fusion: max weight (default: 0.3) */
|
|
89
|
+
maxWeight?: number;
|
|
90
|
+
/** Weighted fusion: hit weight (default: 0.1) */
|
|
91
|
+
hitWeight?: number;
|
|
92
|
+
};
|
|
93
|
+
/** Filter expression (optional) */
|
|
94
|
+
filter?: Record<string, unknown>;
|
|
95
|
+
}
|
|
70
96
|
/** Search result */
|
|
71
97
|
interface SearchResult {
|
|
72
98
|
/** Document ID */
|
|
@@ -121,6 +147,8 @@ interface IVelesDBBackend {
|
|
|
121
147
|
}): Promise<SearchResult[]>;
|
|
122
148
|
/** Execute VelesQL query */
|
|
123
149
|
query(queryString: string, params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
150
|
+
/** Multi-query fusion search */
|
|
151
|
+
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
124
152
|
/** Check if collection is empty */
|
|
125
153
|
isEmpty(collection: string): Promise<boolean>;
|
|
126
154
|
/** Flush pending changes to disk */
|
|
@@ -195,6 +223,20 @@ declare class VelesDB {
|
|
|
195
223
|
* @param config - Collection configuration
|
|
196
224
|
*/
|
|
197
225
|
createCollection(name: string, config: CollectionConfig): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* Create a metadata-only collection (no vectors, just payload data)
|
|
228
|
+
*
|
|
229
|
+
* Useful for storing reference data that can be JOINed with vector collections.
|
|
230
|
+
*
|
|
231
|
+
* @param name - Collection name
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* await db.createMetadataCollection('products');
|
|
236
|
+
* await db.insertMetadata('products', { id: 'P001', name: 'Widget', price: 99 });
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
createMetadataCollection(name: string): Promise<void>;
|
|
198
240
|
/**
|
|
199
241
|
* Delete a collection
|
|
200
242
|
*
|
|
@@ -300,6 +342,34 @@ declare class VelesDB {
|
|
|
300
342
|
* @returns Query results
|
|
301
343
|
*/
|
|
302
344
|
query(queryString: string, params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
345
|
+
/**
|
|
346
|
+
* Multi-query fusion search combining results from multiple query vectors
|
|
347
|
+
*
|
|
348
|
+
* Ideal for RAG pipelines using Multiple Query Generation (MQG).
|
|
349
|
+
*
|
|
350
|
+
* @param collection - Collection name
|
|
351
|
+
* @param vectors - Array of query vectors
|
|
352
|
+
* @param options - Search options (k, fusion strategy, fusionParams, filter)
|
|
353
|
+
* @returns Fused search results
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```typescript
|
|
357
|
+
* // RRF fusion (default)
|
|
358
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2, emb3], {
|
|
359
|
+
* k: 10,
|
|
360
|
+
* fusion: 'rrf',
|
|
361
|
+
* fusionParams: { k: 60 }
|
|
362
|
+
* });
|
|
363
|
+
*
|
|
364
|
+
* // Weighted fusion
|
|
365
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2], {
|
|
366
|
+
* k: 10,
|
|
367
|
+
* fusion: 'weighted',
|
|
368
|
+
* fusionParams: { avgWeight: 0.6, maxWeight: 0.3, hitWeight: 0.1 }
|
|
369
|
+
* });
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
303
373
|
/**
|
|
304
374
|
* Check if a collection is empty
|
|
305
375
|
*
|
|
@@ -366,6 +436,7 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
366
436
|
filter?: Record<string, unknown>;
|
|
367
437
|
}): Promise<SearchResult[]>;
|
|
368
438
|
query(_queryString: string, _params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
439
|
+
multiQuerySearch(_collection: string, _vectors: Array<number[] | Float32Array>, _options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
369
440
|
isEmpty(collectionName: string): Promise<boolean>;
|
|
370
441
|
flush(collectionName: string): Promise<void>;
|
|
371
442
|
close(): Promise<void>;
|
|
@@ -417,9 +488,10 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
417
488
|
filter?: Record<string, unknown>;
|
|
418
489
|
}): Promise<SearchResult[]>;
|
|
419
490
|
query(queryString: string, params?: Record<string, unknown>): Promise<SearchResult[]>;
|
|
491
|
+
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
420
492
|
isEmpty(collection: string): Promise<boolean>;
|
|
421
493
|
flush(collection: string): Promise<void>;
|
|
422
494
|
close(): Promise<void>;
|
|
423
495
|
}
|
|
424
496
|
|
|
425
|
-
export { type BackendType, type Collection, type CollectionConfig, ConnectionError, type DistanceMetric, type IVelesDBBackend, NotFoundError, RestBackend, type SearchOptions, type SearchResult, type StorageMode, ValidationError, type VectorDocument, VelesDB, type VelesDBConfig, VelesDBError, WasmBackend };
|
|
497
|
+
export { type BackendType, type Collection, type CollectionConfig, type CollectionType, ConnectionError, type DistanceMetric, type FusionStrategy, type IVelesDBBackend, type MultiQuerySearchOptions, NotFoundError, RestBackend, type SearchOptions, type SearchResult, type StorageMode, ValidationError, type VectorDocument, VelesDB, type VelesDBConfig, VelesDBError, WasmBackend };
|
package/dist/index.js
CHANGED
|
@@ -129,7 +129,7 @@ var WasmBackend = class {
|
|
|
129
129
|
}
|
|
130
130
|
return {
|
|
131
131
|
name,
|
|
132
|
-
dimension: collection.config.dimension,
|
|
132
|
+
dimension: collection.config.dimension ?? 0,
|
|
133
133
|
metric: collection.config.metric ?? "cosine",
|
|
134
134
|
count: collection.store.len,
|
|
135
135
|
createdAt: collection.createdAt
|
|
@@ -141,7 +141,7 @@ var WasmBackend = class {
|
|
|
141
141
|
for (const [name, data] of this.collections) {
|
|
142
142
|
result.push({
|
|
143
143
|
name,
|
|
144
|
-
dimension: data.config.dimension,
|
|
144
|
+
dimension: data.config.dimension ?? 0,
|
|
145
145
|
metric: data.config.metric ?? "cosine",
|
|
146
146
|
count: data.store.len,
|
|
147
147
|
createdAt: data.createdAt
|
|
@@ -287,6 +287,12 @@ var WasmBackend = class {
|
|
|
287
287
|
"NOT_SUPPORTED"
|
|
288
288
|
);
|
|
289
289
|
}
|
|
290
|
+
async multiQuerySearch(_collection, _vectors, _options) {
|
|
291
|
+
throw new VelesDBError(
|
|
292
|
+
"Multi-query fusion is not supported in WASM backend. Use REST backend for MQF search.",
|
|
293
|
+
"NOT_SUPPORTED"
|
|
294
|
+
);
|
|
295
|
+
}
|
|
290
296
|
async isEmpty(collectionName) {
|
|
291
297
|
this.ensureInitialized();
|
|
292
298
|
const collection = this.collections.get(collectionName);
|
|
@@ -405,6 +411,8 @@ var RestBackend = class {
|
|
|
405
411
|
name,
|
|
406
412
|
dimension: config.dimension,
|
|
407
413
|
metric: config.metric ?? "cosine",
|
|
414
|
+
storage_mode: config.storageMode ?? "full",
|
|
415
|
+
collection_type: config.collectionType ?? "vector",
|
|
408
416
|
description: config.description
|
|
409
417
|
});
|
|
410
418
|
if (response.error) {
|
|
@@ -606,6 +614,30 @@ var RestBackend = class {
|
|
|
606
614
|
}
|
|
607
615
|
return response.data?.results ?? [];
|
|
608
616
|
}
|
|
617
|
+
async multiQuerySearch(collection, vectors, options) {
|
|
618
|
+
this.ensureInitialized();
|
|
619
|
+
const formattedVectors = vectors.map(
|
|
620
|
+
(v) => v instanceof Float32Array ? Array.from(v) : v
|
|
621
|
+
);
|
|
622
|
+
const response = await this.request(
|
|
623
|
+
"POST",
|
|
624
|
+
`/collections/${encodeURIComponent(collection)}/search/multi`,
|
|
625
|
+
{
|
|
626
|
+
vectors: formattedVectors,
|
|
627
|
+
top_k: options?.k ?? 10,
|
|
628
|
+
fusion: options?.fusion ?? "rrf",
|
|
629
|
+
fusion_params: options?.fusionParams ?? { k: 60 },
|
|
630
|
+
filter: options?.filter
|
|
631
|
+
}
|
|
632
|
+
);
|
|
633
|
+
if (response.error) {
|
|
634
|
+
if (response.error.code === "NOT_FOUND") {
|
|
635
|
+
throw new NotFoundError(`Collection '${collection}'`);
|
|
636
|
+
}
|
|
637
|
+
throw new VelesDBError(response.error.message, response.error.code);
|
|
638
|
+
}
|
|
639
|
+
return response.data?.results ?? [];
|
|
640
|
+
}
|
|
609
641
|
async isEmpty(collection) {
|
|
610
642
|
this.ensureInitialized();
|
|
611
643
|
const response = await this.request(
|
|
@@ -706,11 +738,32 @@ var VelesDB = class {
|
|
|
706
738
|
if (!name || typeof name !== "string") {
|
|
707
739
|
throw new ValidationError("Collection name must be a non-empty string");
|
|
708
740
|
}
|
|
709
|
-
|
|
710
|
-
|
|
741
|
+
const isMetadataOnly = config.collectionType === "metadata_only";
|
|
742
|
+
if (!isMetadataOnly && (!config.dimension || config.dimension <= 0)) {
|
|
743
|
+
throw new ValidationError("Dimension must be a positive integer for vector collections");
|
|
711
744
|
}
|
|
712
745
|
await this.backend.createCollection(name, config);
|
|
713
746
|
}
|
|
747
|
+
/**
|
|
748
|
+
* Create a metadata-only collection (no vectors, just payload data)
|
|
749
|
+
*
|
|
750
|
+
* Useful for storing reference data that can be JOINed with vector collections.
|
|
751
|
+
*
|
|
752
|
+
* @param name - Collection name
|
|
753
|
+
*
|
|
754
|
+
* @example
|
|
755
|
+
* ```typescript
|
|
756
|
+
* await db.createMetadataCollection('products');
|
|
757
|
+
* await db.insertMetadata('products', { id: 'P001', name: 'Widget', price: 99 });
|
|
758
|
+
* ```
|
|
759
|
+
*/
|
|
760
|
+
async createMetadataCollection(name) {
|
|
761
|
+
this.ensureInitialized();
|
|
762
|
+
if (!name || typeof name !== "string") {
|
|
763
|
+
throw new ValidationError("Collection name must be a non-empty string");
|
|
764
|
+
}
|
|
765
|
+
await this.backend.createCollection(name, { collectionType: "metadata_only" });
|
|
766
|
+
}
|
|
714
767
|
/**
|
|
715
768
|
* Delete a collection
|
|
716
769
|
*
|
|
@@ -881,6 +934,45 @@ var VelesDB = class {
|
|
|
881
934
|
}
|
|
882
935
|
return this.backend.query(queryString, params);
|
|
883
936
|
}
|
|
937
|
+
/**
|
|
938
|
+
* Multi-query fusion search combining results from multiple query vectors
|
|
939
|
+
*
|
|
940
|
+
* Ideal for RAG pipelines using Multiple Query Generation (MQG).
|
|
941
|
+
*
|
|
942
|
+
* @param collection - Collection name
|
|
943
|
+
* @param vectors - Array of query vectors
|
|
944
|
+
* @param options - Search options (k, fusion strategy, fusionParams, filter)
|
|
945
|
+
* @returns Fused search results
|
|
946
|
+
*
|
|
947
|
+
* @example
|
|
948
|
+
* ```typescript
|
|
949
|
+
* // RRF fusion (default)
|
|
950
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2, emb3], {
|
|
951
|
+
* k: 10,
|
|
952
|
+
* fusion: 'rrf',
|
|
953
|
+
* fusionParams: { k: 60 }
|
|
954
|
+
* });
|
|
955
|
+
*
|
|
956
|
+
* // Weighted fusion
|
|
957
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2], {
|
|
958
|
+
* k: 10,
|
|
959
|
+
* fusion: 'weighted',
|
|
960
|
+
* fusionParams: { avgWeight: 0.6, maxWeight: 0.3, hitWeight: 0.1 }
|
|
961
|
+
* });
|
|
962
|
+
* ```
|
|
963
|
+
*/
|
|
964
|
+
async multiQuerySearch(collection, vectors, options) {
|
|
965
|
+
this.ensureInitialized();
|
|
966
|
+
if (!Array.isArray(vectors) || vectors.length === 0) {
|
|
967
|
+
throw new ValidationError("Vectors must be a non-empty array");
|
|
968
|
+
}
|
|
969
|
+
for (const v of vectors) {
|
|
970
|
+
if (!Array.isArray(v) && !(v instanceof Float32Array)) {
|
|
971
|
+
throw new ValidationError("Each vector must be an array or Float32Array");
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
return this.backend.multiQuerySearch(collection, vectors, options);
|
|
975
|
+
}
|
|
884
976
|
/**
|
|
885
977
|
* Check if a collection is empty
|
|
886
978
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -87,7 +87,7 @@ var WasmBackend = class {
|
|
|
87
87
|
}
|
|
88
88
|
return {
|
|
89
89
|
name,
|
|
90
|
-
dimension: collection.config.dimension,
|
|
90
|
+
dimension: collection.config.dimension ?? 0,
|
|
91
91
|
metric: collection.config.metric ?? "cosine",
|
|
92
92
|
count: collection.store.len,
|
|
93
93
|
createdAt: collection.createdAt
|
|
@@ -99,7 +99,7 @@ var WasmBackend = class {
|
|
|
99
99
|
for (const [name, data] of this.collections) {
|
|
100
100
|
result.push({
|
|
101
101
|
name,
|
|
102
|
-
dimension: data.config.dimension,
|
|
102
|
+
dimension: data.config.dimension ?? 0,
|
|
103
103
|
metric: data.config.metric ?? "cosine",
|
|
104
104
|
count: data.store.len,
|
|
105
105
|
createdAt: data.createdAt
|
|
@@ -245,6 +245,12 @@ var WasmBackend = class {
|
|
|
245
245
|
"NOT_SUPPORTED"
|
|
246
246
|
);
|
|
247
247
|
}
|
|
248
|
+
async multiQuerySearch(_collection, _vectors, _options) {
|
|
249
|
+
throw new VelesDBError(
|
|
250
|
+
"Multi-query fusion is not supported in WASM backend. Use REST backend for MQF search.",
|
|
251
|
+
"NOT_SUPPORTED"
|
|
252
|
+
);
|
|
253
|
+
}
|
|
248
254
|
async isEmpty(collectionName) {
|
|
249
255
|
this.ensureInitialized();
|
|
250
256
|
const collection = this.collections.get(collectionName);
|
|
@@ -363,6 +369,8 @@ var RestBackend = class {
|
|
|
363
369
|
name,
|
|
364
370
|
dimension: config.dimension,
|
|
365
371
|
metric: config.metric ?? "cosine",
|
|
372
|
+
storage_mode: config.storageMode ?? "full",
|
|
373
|
+
collection_type: config.collectionType ?? "vector",
|
|
366
374
|
description: config.description
|
|
367
375
|
});
|
|
368
376
|
if (response.error) {
|
|
@@ -564,6 +572,30 @@ var RestBackend = class {
|
|
|
564
572
|
}
|
|
565
573
|
return response.data?.results ?? [];
|
|
566
574
|
}
|
|
575
|
+
async multiQuerySearch(collection, vectors, options) {
|
|
576
|
+
this.ensureInitialized();
|
|
577
|
+
const formattedVectors = vectors.map(
|
|
578
|
+
(v) => v instanceof Float32Array ? Array.from(v) : v
|
|
579
|
+
);
|
|
580
|
+
const response = await this.request(
|
|
581
|
+
"POST",
|
|
582
|
+
`/collections/${encodeURIComponent(collection)}/search/multi`,
|
|
583
|
+
{
|
|
584
|
+
vectors: formattedVectors,
|
|
585
|
+
top_k: options?.k ?? 10,
|
|
586
|
+
fusion: options?.fusion ?? "rrf",
|
|
587
|
+
fusion_params: options?.fusionParams ?? { k: 60 },
|
|
588
|
+
filter: options?.filter
|
|
589
|
+
}
|
|
590
|
+
);
|
|
591
|
+
if (response.error) {
|
|
592
|
+
if (response.error.code === "NOT_FOUND") {
|
|
593
|
+
throw new NotFoundError(`Collection '${collection}'`);
|
|
594
|
+
}
|
|
595
|
+
throw new VelesDBError(response.error.message, response.error.code);
|
|
596
|
+
}
|
|
597
|
+
return response.data?.results ?? [];
|
|
598
|
+
}
|
|
567
599
|
async isEmpty(collection) {
|
|
568
600
|
this.ensureInitialized();
|
|
569
601
|
const response = await this.request(
|
|
@@ -664,11 +696,32 @@ var VelesDB = class {
|
|
|
664
696
|
if (!name || typeof name !== "string") {
|
|
665
697
|
throw new ValidationError("Collection name must be a non-empty string");
|
|
666
698
|
}
|
|
667
|
-
|
|
668
|
-
|
|
699
|
+
const isMetadataOnly = config.collectionType === "metadata_only";
|
|
700
|
+
if (!isMetadataOnly && (!config.dimension || config.dimension <= 0)) {
|
|
701
|
+
throw new ValidationError("Dimension must be a positive integer for vector collections");
|
|
669
702
|
}
|
|
670
703
|
await this.backend.createCollection(name, config);
|
|
671
704
|
}
|
|
705
|
+
/**
|
|
706
|
+
* Create a metadata-only collection (no vectors, just payload data)
|
|
707
|
+
*
|
|
708
|
+
* Useful for storing reference data that can be JOINed with vector collections.
|
|
709
|
+
*
|
|
710
|
+
* @param name - Collection name
|
|
711
|
+
*
|
|
712
|
+
* @example
|
|
713
|
+
* ```typescript
|
|
714
|
+
* await db.createMetadataCollection('products');
|
|
715
|
+
* await db.insertMetadata('products', { id: 'P001', name: 'Widget', price: 99 });
|
|
716
|
+
* ```
|
|
717
|
+
*/
|
|
718
|
+
async createMetadataCollection(name) {
|
|
719
|
+
this.ensureInitialized();
|
|
720
|
+
if (!name || typeof name !== "string") {
|
|
721
|
+
throw new ValidationError("Collection name must be a non-empty string");
|
|
722
|
+
}
|
|
723
|
+
await this.backend.createCollection(name, { collectionType: "metadata_only" });
|
|
724
|
+
}
|
|
672
725
|
/**
|
|
673
726
|
* Delete a collection
|
|
674
727
|
*
|
|
@@ -839,6 +892,45 @@ var VelesDB = class {
|
|
|
839
892
|
}
|
|
840
893
|
return this.backend.query(queryString, params);
|
|
841
894
|
}
|
|
895
|
+
/**
|
|
896
|
+
* Multi-query fusion search combining results from multiple query vectors
|
|
897
|
+
*
|
|
898
|
+
* Ideal for RAG pipelines using Multiple Query Generation (MQG).
|
|
899
|
+
*
|
|
900
|
+
* @param collection - Collection name
|
|
901
|
+
* @param vectors - Array of query vectors
|
|
902
|
+
* @param options - Search options (k, fusion strategy, fusionParams, filter)
|
|
903
|
+
* @returns Fused search results
|
|
904
|
+
*
|
|
905
|
+
* @example
|
|
906
|
+
* ```typescript
|
|
907
|
+
* // RRF fusion (default)
|
|
908
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2, emb3], {
|
|
909
|
+
* k: 10,
|
|
910
|
+
* fusion: 'rrf',
|
|
911
|
+
* fusionParams: { k: 60 }
|
|
912
|
+
* });
|
|
913
|
+
*
|
|
914
|
+
* // Weighted fusion
|
|
915
|
+
* const results = await db.multiQuerySearch('docs', [emb1, emb2], {
|
|
916
|
+
* k: 10,
|
|
917
|
+
* fusion: 'weighted',
|
|
918
|
+
* fusionParams: { avgWeight: 0.6, maxWeight: 0.3, hitWeight: 0.1 }
|
|
919
|
+
* });
|
|
920
|
+
* ```
|
|
921
|
+
*/
|
|
922
|
+
async multiQuerySearch(collection, vectors, options) {
|
|
923
|
+
this.ensureInitialized();
|
|
924
|
+
if (!Array.isArray(vectors) || vectors.length === 0) {
|
|
925
|
+
throw new ValidationError("Vectors must be a non-empty array");
|
|
926
|
+
}
|
|
927
|
+
for (const v of vectors) {
|
|
928
|
+
if (!Array.isArray(v) && !(v instanceof Float32Array)) {
|
|
929
|
+
throw new ValidationError("Each vector must be an array or Float32Array");
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return this.backend.multiQuerySearch(collection, vectors, options);
|
|
933
|
+
}
|
|
842
934
|
/**
|
|
843
935
|
* Check if a collection is empty
|
|
844
936
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiscale/velesdb-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "VelesDB TypeScript SDK: The Local Vector Database for AI & RAG. Microsecond semantic search in Browser & Node.js.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -30,14 +30,17 @@
|
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"velesdb",
|
|
33
|
-
"vector",
|
|
34
|
-
"database",
|
|
35
|
-
"similarity-search",
|
|
33
|
+
"vector-database",
|
|
36
34
|
"embeddings",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
35
|
+
"rag",
|
|
36
|
+
"local-first",
|
|
37
|
+
"ai-memory",
|
|
38
|
+
"semantic-search",
|
|
39
|
+
"sqlite-alternative",
|
|
39
40
|
"wasm",
|
|
40
|
-
"typescript"
|
|
41
|
+
"typescript",
|
|
42
|
+
"langchain",
|
|
43
|
+
"llm"
|
|
41
44
|
],
|
|
42
45
|
"author": "Wiscale France",
|
|
43
46
|
"license": "MIT",
|
|
@@ -63,7 +66,7 @@
|
|
|
63
66
|
"vitest": "^4.0.16"
|
|
64
67
|
},
|
|
65
68
|
"dependencies": {
|
|
66
|
-
"@wiscale/velesdb-wasm": "^1.
|
|
69
|
+
"@wiscale/velesdb-wasm": "^1.1.0"
|
|
67
70
|
},
|
|
68
71
|
"engines": {
|
|
69
72
|
"node": ">=18.0.0"
|