@mastra/pg 0.1.6-alpha.1 → 0.1.6-alpha.4

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.
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
1
+ import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach, vi } from 'vitest';
2
2
 
3
3
  import { PgVector } from '.';
4
4
 
@@ -27,32 +27,39 @@ describe('PgVector', () => {
27
27
  });
28
28
 
29
29
  it('should create a new vector table with specified dimensions', async () => {
30
- await vectorDB.createIndex(testIndexName, 3);
30
+ await vectorDB.createIndex({ indexName: testIndexName, dimension: 3 });
31
31
  const stats = await vectorDB.describeIndex(testIndexName);
32
32
  expect(stats?.dimension).toBe(3);
33
33
  expect(stats?.count).toBe(0);
34
34
  });
35
35
 
36
36
  it('should create index with specified metric', async () => {
37
- await vectorDB.createIndex(testIndexName2, 3, 'euclidean');
37
+ await vectorDB.createIndex({ indexName: testIndexName2, dimension: 3, metric: 'euclidean' });
38
38
  const stats = await vectorDB.describeIndex(testIndexName2);
39
39
  expect(stats.metric).toBe('euclidean');
40
40
  });
41
41
 
42
42
  it('should throw error if dimension is invalid', async () => {
43
- await expect(vectorDB.createIndex(`testIndexNameFail`, 0)).rejects.toThrow();
43
+ await expect(vectorDB.createIndex({ indexName: 'testIndexNameFail', dimension: 0 })).rejects.toThrow();
44
44
  });
45
45
 
46
46
  it('should create index with flat type', async () => {
47
- await vectorDB.createIndex(testIndexName2, 3, 'cosine', { type: 'flat' });
47
+ await vectorDB.createIndex({
48
+ indexName: testIndexName2,
49
+ dimension: 3,
50
+ metric: 'cosine',
51
+ indexConfig: { type: 'flat' },
52
+ });
48
53
  const stats = await vectorDB.describeIndex(testIndexName2);
49
54
  expect(stats.type).toBe('flat');
50
55
  });
51
56
 
52
57
  it('should create index with hnsw type', async () => {
53
- await vectorDB.createIndex(testIndexName2, 3, 'cosine', {
54
- type: 'hnsw',
55
- hnsw: { m: 16, efConstruction: 64 }, // Any reasonable values work
58
+ await vectorDB.createIndex({
59
+ indexName: testIndexName2,
60
+ dimension: 3,
61
+ metric: 'cosine',
62
+ indexConfig: { type: 'hnsw', hnsw: { m: 16, efConstruction: 64 } }, // Any reasonable values work
56
63
  });
57
64
  const stats = await vectorDB.describeIndex(testIndexName2);
58
65
  expect(stats.type).toBe('hnsw');
@@ -60,9 +67,11 @@ describe('PgVector', () => {
60
67
  });
61
68
 
62
69
  it('should create index with ivfflat type and lists', async () => {
63
- await vectorDB.createIndex(testIndexName2, 3, 'cosine', {
64
- type: 'ivfflat',
65
- ivf: { lists: 100 },
70
+ await vectorDB.createIndex({
71
+ indexName: testIndexName2,
72
+ dimension: 3,
73
+ metric: 'cosine',
74
+ indexConfig: { type: 'ivfflat', ivf: { lists: 100 } },
66
75
  });
67
76
  const stats = await vectorDB.describeIndex(testIndexName2);
68
77
  expect(stats.type).toBe('ivfflat');
@@ -73,7 +82,7 @@ describe('PgVector', () => {
73
82
  describe('listIndexes', () => {
74
83
  const indexName = 'test_query_3';
75
84
  beforeAll(async () => {
76
- await vectorDB.createIndex(indexName, 3);
85
+ await vectorDB.createIndex({ indexName, dimension: 3 });
77
86
  });
78
87
 
79
88
  afterAll(async () => {
@@ -95,7 +104,7 @@ describe('PgVector', () => {
95
104
  describe('describeIndex', () => {
96
105
  const indexName = 'test_query_4';
97
106
  beforeAll(async () => {
98
- await vectorDB.createIndex(indexName, 3);
107
+ await vectorDB.createIndex({ indexName, dimension: 3 });
99
108
  });
100
109
 
101
110
  afterAll(async () => {
@@ -103,12 +112,12 @@ describe('PgVector', () => {
103
112
  });
104
113
 
105
114
  it('should return correct index stats', async () => {
106
- await vectorDB.createIndex(indexName, 3, 'cosine');
115
+ await vectorDB.createIndex({ indexName, dimension: 3, metric: 'cosine' });
107
116
  const vectors = [
108
117
  [1, 2, 3],
109
118
  [4, 5, 6],
110
119
  ];
111
- await vectorDB.upsert(indexName, vectors);
120
+ await vectorDB.upsert({ indexName, vectors });
112
121
 
113
122
  const stats = await vectorDB.describeIndex(indexName);
114
123
  expect(stats).toEqual({
@@ -126,13 +135,50 @@ describe('PgVector', () => {
126
135
  await expect(vectorDB.describeIndex('non_existent')).rejects.toThrow();
127
136
  });
128
137
  });
138
+
139
+ describe('buildIndex', () => {
140
+ const indexName = 'test_build_index';
141
+ beforeAll(async () => {
142
+ await vectorDB.createIndex({ indexName, dimension: 3 });
143
+ });
144
+
145
+ afterAll(async () => {
146
+ await vectorDB.deleteIndex(indexName);
147
+ });
148
+
149
+ it('should build index with specified metric and config', async () => {
150
+ await vectorDB.buildIndex({
151
+ indexName,
152
+ metric: 'cosine',
153
+ indexConfig: { type: 'hnsw', hnsw: { m: 16, efConstruction: 64 } },
154
+ });
155
+
156
+ const stats = await vectorDB.describeIndex(indexName);
157
+ expect(stats.type).toBe('hnsw');
158
+ expect(stats.metric).toBe('cosine');
159
+ expect(stats.config.m).toBe(16);
160
+ });
161
+
162
+ it('should build ivfflat index with specified lists', async () => {
163
+ await vectorDB.buildIndex({
164
+ indexName,
165
+ metric: 'euclidean',
166
+ indexConfig: { type: 'ivfflat', ivf: { lists: 100 } },
167
+ });
168
+
169
+ const stats = await vectorDB.describeIndex(indexName);
170
+ expect(stats.type).toBe('ivfflat');
171
+ expect(stats.metric).toBe('euclidean');
172
+ expect(stats.config.lists).toBe(100);
173
+ });
174
+ });
129
175
  });
130
176
 
131
177
  // Vector Operations Tests
132
178
  describe('Vector Operations', () => {
133
179
  describe('upsert', () => {
134
180
  beforeEach(async () => {
135
- await vectorDB.createIndex(testIndexName, 3);
181
+ await vectorDB.createIndex({ indexName: testIndexName, dimension: 3 });
136
182
  });
137
183
 
138
184
  afterEach(async () => {
@@ -144,7 +190,7 @@ describe('PgVector', () => {
144
190
  [1, 2, 3],
145
191
  [4, 5, 6],
146
192
  ];
147
- const ids = await vectorDB.upsert(testIndexName, vectors);
193
+ const ids = await vectorDB.upsert({ indexName: testIndexName, vectors });
148
194
 
149
195
  expect(ids).toHaveLength(2);
150
196
  const stats = await vectorDB.describeIndex(testIndexName);
@@ -154,13 +200,18 @@ describe('PgVector', () => {
154
200
  it('should update existing vectors', async () => {
155
201
  const vectors = [[1, 2, 3]];
156
202
  const metadata = [{ test: 'initial' }];
157
- const [id] = await vectorDB.upsert(testIndexName, vectors, metadata);
203
+ const [id] = await vectorDB.upsert({ indexName: testIndexName, vectors, metadata });
158
204
 
159
205
  const updatedVectors = [[4, 5, 6]];
160
206
  const updatedMetadata = [{ test: 'updated' }];
161
- await vectorDB.upsert(testIndexName, updatedVectors, updatedMetadata, [id!]);
207
+ await vectorDB.upsert({
208
+ indexName: testIndexName,
209
+ vectors: updatedVectors,
210
+ metadata: updatedMetadata,
211
+ ids: [id!],
212
+ });
162
213
 
163
- const results = await vectorDB.query(testIndexName, [4, 5, 6], 1);
214
+ const results = await vectorDB.query({ indexName: testIndexName, queryVector: [4, 5, 6], topK: 1 });
164
215
  expect(results[0]?.id).toBe(id);
165
216
  expect(results[0]?.metadata).toEqual({ test: 'updated' });
166
217
  });
@@ -169,15 +220,15 @@ describe('PgVector', () => {
169
220
  const vectors = [[1, 2, 3]];
170
221
  const metadata = [{ test: 'value', num: 123 }];
171
222
 
172
- await vectorDB.upsert(testIndexName, vectors, metadata);
173
- const results = await vectorDB.query(testIndexName, [1, 2, 3], 1);
223
+ await vectorDB.upsert({ indexName: testIndexName, vectors, metadata });
224
+ const results = await vectorDB.query({ indexName: testIndexName, queryVector: [1, 2, 3], topK: 1 });
174
225
 
175
226
  expect(results[0]?.metadata).toEqual(metadata[0]);
176
227
  });
177
228
 
178
229
  it('should throw error if vector dimensions dont match', async () => {
179
230
  const vectors = [[1, 2, 3, 4]]; // 4D vector for 3D index
180
- await expect(vectorDB.upsert(testIndexName, vectors)).rejects.toThrow();
231
+ await expect(vectorDB.upsert({ indexName: testIndexName, vectors })).rejects.toThrow();
181
232
  });
182
233
  });
183
234
 
@@ -190,7 +241,7 @@ describe('PgVector', () => {
190
241
  } catch {
191
242
  // Ignore if doesn't exist
192
243
  }
193
- await vectorDB.createIndex(indexName, 3);
244
+ await vectorDB.createIndex({ indexName, dimension: 3 });
194
245
  });
195
246
 
196
247
  beforeEach(async () => {
@@ -205,7 +256,7 @@ describe('PgVector', () => {
205
256
  { type: 'b', value: 2 },
206
257
  { type: 'a', value: 3 },
207
258
  ];
208
- await vectorDB.upsert(indexName, vectors, metadata);
259
+ await vectorDB.upsert({ indexName, vectors, metadata });
209
260
  });
210
261
 
211
262
  afterAll(async () => {
@@ -213,25 +264,30 @@ describe('PgVector', () => {
213
264
  });
214
265
 
215
266
  it('should return closest vectors', async () => {
216
- const results = await vectorDB.query(indexName, [1, 0, 0], 1);
267
+ const results = await vectorDB.query({ indexName, queryVector: [1, 0, 0], topK: 1 });
217
268
  expect(results).toHaveLength(1);
218
269
  expect(results[0]?.vector).toBe(undefined);
219
270
  expect(results[0]?.score).toBeCloseTo(1, 5);
220
271
  });
221
272
 
222
273
  it('should return vector with result', async () => {
223
- const results = await vectorDB.query(indexName, [1, 0, 0], 1, undefined, true);
274
+ const results = await vectorDB.query({ indexName, queryVector: [1, 0, 0], topK: 1, includeVector: true });
224
275
  expect(results).toHaveLength(1);
225
276
  expect(results[0]?.vector).toStrictEqual([1, 0, 0]);
226
277
  });
227
278
 
228
279
  it('should respect topK parameter', async () => {
229
- const results = await vectorDB.query(indexName, [1, 0, 0], 2);
280
+ const results = await vectorDB.query({ indexName, queryVector: [1, 0, 0], topK: 2 });
230
281
  expect(results).toHaveLength(2);
231
282
  });
232
283
 
233
284
  it('should handle filters correctly', async () => {
234
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, { type: 'a' });
285
+ const results = await vectorDB.query({
286
+ indexName,
287
+ queryVector: [1, 0, 0],
288
+ topK: 10,
289
+ filter: { type: 'a' },
290
+ });
235
291
 
236
292
  expect(results).toHaveLength(1);
237
293
  results.forEach(result => {
@@ -251,7 +307,7 @@ describe('PgVector', () => {
251
307
  } catch {
252
308
  // Ignore if doesn't exist
253
309
  }
254
- await vectorDB.createIndex(indexName, 3);
310
+ await vectorDB.createIndex({ indexName, dimension: 3 });
255
311
  });
256
312
 
257
313
  beforeEach(async () => {
@@ -301,7 +357,7 @@ describe('PgVector', () => {
301
357
  { category: 'clothing', price: 60, tags: ['new'], active: true },
302
358
  ];
303
359
 
304
- await vectorDB.upsert(indexName, vectors, metadata);
360
+ await vectorDB.upsert({ indexName, vectors, metadata });
305
361
  });
306
362
 
307
363
  afterAll(async () => {
@@ -312,26 +368,32 @@ describe('PgVector', () => {
312
368
  describe('Comparison Operators', () => {
313
369
  it('should handle numeric string comparisons', async () => {
314
370
  // Insert a record with numeric string
315
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ numericString: '123' }]);
371
+ await vectorDB.upsert({ indexName, vectors: [[1, 0.1, 0]], metadata: [{ numericString: '123' }] });
316
372
 
317
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
318
- numericString: { $gt: '100' }, // Compare strings numerically
373
+ const results = await vectorDB.query({
374
+ indexName,
375
+ queryVector: [1, 0, 0],
376
+ filter: { numericString: { $gt: '100' } },
319
377
  });
320
378
  expect(results.length).toBeGreaterThan(0);
321
379
  expect(results[0]?.metadata?.numericString).toBe('123');
322
380
  });
323
381
 
324
382
  it('should filter with $gt operator', async () => {
325
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
326
- price: { $gt: 75 },
383
+ const results = await vectorDB.query({
384
+ indexName,
385
+ queryVector: [1, 0, 0],
386
+ filter: { price: { $gt: 75 } },
327
387
  });
328
388
  expect(results).toHaveLength(1);
329
389
  expect(results[0]?.metadata?.price).toBe(100);
330
390
  });
331
391
 
332
392
  it('should filter with $lte operator', async () => {
333
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
334
- price: { $lte: 50 },
393
+ const results = await vectorDB.query({
394
+ indexName,
395
+ queryVector: [1, 0, 0],
396
+ filter: { price: { $lte: 50 } },
335
397
  });
336
398
  expect(results).toHaveLength(2);
337
399
  results.forEach(result => {
@@ -340,8 +402,10 @@ describe('PgVector', () => {
340
402
  });
341
403
 
342
404
  it('should filter with lt operator', async () => {
343
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
344
- price: { $lt: 60 },
405
+ const results = await vectorDB.query({
406
+ indexName,
407
+ queryVector: [1, 0, 0],
408
+ filter: { price: { $lt: 60 } },
345
409
  });
346
410
  expect(results).toHaveLength(2);
347
411
  results.forEach(result => {
@@ -350,8 +414,10 @@ describe('PgVector', () => {
350
414
  });
351
415
 
352
416
  it('should filter with gte operator', async () => {
353
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
354
- price: { $gte: 75 },
417
+ const results = await vectorDB.query({
418
+ indexName,
419
+ queryVector: [1, 0, 0],
420
+ filter: { price: { $gte: 75 } },
355
421
  });
356
422
  expect(results).toHaveLength(2);
357
423
  results.forEach(result => {
@@ -360,8 +426,10 @@ describe('PgVector', () => {
360
426
  });
361
427
 
362
428
  it('should filter with ne operator', async () => {
363
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
364
- category: { $ne: 'electronics' },
429
+ const results = await vectorDB.query({
430
+ indexName,
431
+ queryVector: [1, 0, 0],
432
+ filter: { category: { $ne: 'electronics' } },
365
433
  });
366
434
  expect(results.length).toBeGreaterThan(0);
367
435
  results.forEach(result => {
@@ -370,8 +438,10 @@ describe('PgVector', () => {
370
438
  });
371
439
 
372
440
  it('should filter with $gt and $lte operator', async () => {
373
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
374
- price: { $gt: 70, $lte: 100 },
441
+ const results = await vectorDB.query({
442
+ indexName,
443
+ queryVector: [1, 0, 0],
444
+ filter: { price: { $gt: 70, $lte: 100 } },
375
445
  });
376
446
  expect(results).toHaveLength(2);
377
447
  results.forEach(result => {
@@ -384,8 +454,10 @@ describe('PgVector', () => {
384
454
  // Array Operator Tests
385
455
  describe('Array Operators', () => {
386
456
  it('should filter with $in operator', async () => {
387
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
388
- category: { $in: ['electronics', 'clothing'] },
457
+ const results = await vectorDB.query({
458
+ indexName,
459
+ queryVector: [1, 0, 0],
460
+ filter: { category: { $in: ['electronics', 'clothing'] } },
389
461
  });
390
462
  expect(results).toHaveLength(3);
391
463
  results.forEach(result => {
@@ -394,8 +466,10 @@ describe('PgVector', () => {
394
466
  });
395
467
 
396
468
  it('should filter with $nin operator', async () => {
397
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
398
- category: { $nin: ['electronics', 'books'] },
469
+ const results = await vectorDB.query({
470
+ indexName,
471
+ queryVector: [1, 0, 0],
472
+ filter: { category: { $nin: ['electronics', 'books'] } },
399
473
  });
400
474
  expect(results.length).toBeGreaterThan(0);
401
475
  results.forEach(result => {
@@ -405,21 +479,27 @@ describe('PgVector', () => {
405
479
 
406
480
  it('should handle empty arrays in in/nin operators', async () => {
407
481
  // Should return no results for empty IN
408
- const resultsIn = await vectorDB.query(indexName, [1, 0, 0], 10, {
409
- category: { $in: [] },
482
+ const resultsIn = await vectorDB.query({
483
+ indexName,
484
+ queryVector: [1, 0, 0],
485
+ filter: { category: { $in: [] } },
410
486
  });
411
487
  expect(resultsIn).toHaveLength(0);
412
488
 
413
489
  // Should return all results for empty NIN
414
- const resultsNin = await vectorDB.query(indexName, [1, 0, 0], 10, {
415
- category: { $nin: [] },
490
+ const resultsNin = await vectorDB.query({
491
+ indexName,
492
+ queryVector: [1, 0, 0],
493
+ filter: { category: { $nin: [] } },
416
494
  });
417
495
  expect(resultsNin.length).toBeGreaterThan(0);
418
496
  });
419
497
 
420
498
  it('should filter with array $contains operator', async () => {
421
- const results = await vectorDB.query(indexName, [1, 0.1, 0], 10, {
422
- tags: { $contains: ['new'] },
499
+ const results = await vectorDB.query({
500
+ indexName,
501
+ queryVector: [1, 0.1, 0],
502
+ filter: { tags: { $contains: ['new'] } },
423
503
  });
424
504
  expect(results.length).toBeGreaterThan(0);
425
505
  results.forEach(result => {
@@ -428,12 +508,10 @@ describe('PgVector', () => {
428
508
  });
429
509
 
430
510
  it('should filter with $elemMatch operator', async () => {
431
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
432
- tags: {
433
- $elemMatch: {
434
- $in: ['new', 'premium'],
435
- },
436
- },
511
+ const results = await vectorDB.query({
512
+ indexName,
513
+ queryVector: [1, 0, 0],
514
+ filter: { tags: { $elemMatch: { $in: ['new', 'premium'] } } },
437
515
  });
438
516
  expect(results.length).toBeGreaterThan(0);
439
517
  results.forEach(result => {
@@ -442,25 +520,20 @@ describe('PgVector', () => {
442
520
  });
443
521
 
444
522
  it('should filter with $elemMatch using equality', async () => {
445
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
446
- tags: {
447
- $elemMatch: {
448
- $eq: 'sale',
449
- },
450
- },
523
+ const results = await vectorDB.query({
524
+ indexName,
525
+ queryVector: [1, 0, 0],
526
+ filter: { tags: { $elemMatch: { $eq: 'sale' } } },
451
527
  });
452
528
  expect(results).toHaveLength(1);
453
529
  expect(results[0]?.metadata?.tags).toContain('sale');
454
530
  });
455
531
 
456
532
  it('should filter with $elemMatch using multiple conditions', async () => {
457
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
458
- ratings: {
459
- $elemMatch: {
460
- $gt: 4,
461
- $lt: 4.5,
462
- },
463
- },
533
+ const results = await vectorDB.query({
534
+ indexName,
535
+ queryVector: [1, 0, 0],
536
+ filter: { ratings: { $elemMatch: { $gt: 4, $lt: 4.5 } } },
464
537
  });
465
538
  expect(results.length).toBeGreaterThan(0);
466
539
  results.forEach(result => {
@@ -470,13 +543,10 @@ describe('PgVector', () => {
470
543
  });
471
544
 
472
545
  it('should handle complex $elemMatch conditions', async () => {
473
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
474
- stock: {
475
- $elemMatch: {
476
- location: 'A',
477
- count: { $gt: 20 },
478
- },
479
- },
546
+ const results = await vectorDB.query({
547
+ indexName,
548
+ queryVector: [1, 0, 0],
549
+ filter: { stock: { $elemMatch: { location: 'A', count: { $gt: 20 } } } },
480
550
  });
481
551
  expect(results.length).toBeGreaterThan(0);
482
552
  results.forEach(result => {
@@ -486,12 +556,10 @@ describe('PgVector', () => {
486
556
  });
487
557
 
488
558
  it('should filter with $elemMatch on nested numeric fields', async () => {
489
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
490
- reviews: {
491
- $elemMatch: {
492
- score: { $gt: 4 },
493
- },
494
- },
559
+ const results = await vectorDB.query({
560
+ indexName,
561
+ queryVector: [1, 0, 0],
562
+ filter: { reviews: { $elemMatch: { score: { $gt: 4 } } } },
495
563
  });
496
564
  expect(results.length).toBeGreaterThan(0);
497
565
  results.forEach(result => {
@@ -500,13 +568,10 @@ describe('PgVector', () => {
500
568
  });
501
569
 
502
570
  it('should filter with $elemMatch on multiple nested fields', async () => {
503
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
504
- reviews: {
505
- $elemMatch: {
506
- score: { $gte: 4 },
507
- verified: true,
508
- },
509
- },
571
+ const results = await vectorDB.query({
572
+ indexName,
573
+ queryVector: [1, 0, 0],
574
+ filter: { reviews: { $elemMatch: { score: { $gte: 4 }, verified: true } } },
510
575
  });
511
576
  expect(results.length).toBeGreaterThan(0);
512
577
  results.forEach(result => {
@@ -515,31 +580,29 @@ describe('PgVector', () => {
515
580
  });
516
581
 
517
582
  it('should filter with $elemMatch on exact string match', async () => {
518
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
519
- reviews: {
520
- $elemMatch: {
521
- user: 'alice',
522
- },
523
- },
583
+ const results = await vectorDB.query({
584
+ indexName,
585
+ queryVector: [1, 0, 0],
586
+ filter: { reviews: { $elemMatch: { user: 'alice' } } },
524
587
  });
525
588
  expect(results).toHaveLength(1);
526
589
  expect(results[0].metadata?.reviews.some(r => r.user === 'alice')).toBe(true);
527
590
  });
528
591
 
529
592
  it('should handle $elemMatch with no matches', async () => {
530
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
531
- reviews: {
532
- $elemMatch: {
533
- score: 10, // No review has score 10
534
- },
535
- },
593
+ const results = await vectorDB.query({
594
+ indexName,
595
+ queryVector: [1, 0, 0],
596
+ filter: { reviews: { $elemMatch: { score: 10 } } },
536
597
  });
537
598
  expect(results).toHaveLength(0);
538
599
  });
539
600
 
540
601
  it('should filter with $all operator', async () => {
541
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
542
- tags: { $all: ['used', 'sale'] },
602
+ const results = await vectorDB.query({
603
+ indexName,
604
+ queryVector: [1, 0, 0],
605
+ filter: { tags: { $all: ['used', 'sale'] } },
543
606
  });
544
607
  expect(results).toHaveLength(1);
545
608
  results.forEach(result => {
@@ -549,8 +612,10 @@ describe('PgVector', () => {
549
612
  });
550
613
 
551
614
  it('should filter with $all using single value', async () => {
552
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
553
- tags: { $all: ['new'] },
615
+ const results = await vectorDB.query({
616
+ indexName,
617
+ queryVector: [1, 0, 0],
618
+ filter: { tags: { $all: ['new'] } },
554
619
  });
555
620
  expect(results.length).toBeGreaterThan(0);
556
621
  results.forEach(result => {
@@ -559,26 +624,32 @@ describe('PgVector', () => {
559
624
  });
560
625
 
561
626
  it('should handle empty array for $all', async () => {
562
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
563
- tags: { $all: [] },
627
+ const results = await vectorDB.query({
628
+ indexName,
629
+ queryVector: [1, 0, 0],
630
+ filter: { tags: { $all: [] } },
564
631
  });
565
632
  expect(results).toHaveLength(0);
566
633
  });
567
634
 
568
635
  it('should handle non-array field $all', async () => {
569
636
  // First insert a record with non-array field
570
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ tags: 'not-an-array' }]);
637
+ await vectorDB.upsert({ indexName, vectors: [[1, 0.1, 0]], metadata: [{ tags: 'not-an-array' }] });
571
638
 
572
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
573
- tags: { $all: ['value'] },
639
+ const results = await vectorDB.query({
640
+ indexName,
641
+ queryVector: [1, 0, 0],
642
+ filter: { tags: { $all: ['value'] } },
574
643
  });
575
644
  expect(results).toHaveLength(0);
576
645
  });
577
646
 
578
647
  // Contains Operator Tests
579
648
  it('should filter with contains operator for exact field match', async () => {
580
- const results = await vectorDB.query(indexName, [1, 0.1, 0], 10, {
581
- category: { $contains: 'electronics' },
649
+ const results = await vectorDB.query({
650
+ indexName,
651
+ queryVector: [1, 0.1, 0],
652
+ filter: { category: { $contains: 'electronics' } },
582
653
  });
583
654
  expect(results.length).toBeGreaterThan(0);
584
655
  results.forEach(result => {
@@ -588,19 +659,21 @@ describe('PgVector', () => {
588
659
 
589
660
  it('should filter with $contains operator for nested objects', async () => {
590
661
  // First insert a record with nested object
591
- await vectorDB.upsert(
662
+ await vectorDB.upsert({
592
663
  indexName,
593
- [[1, 0.1, 0]],
594
- [
664
+ vectors: [[1, 0.1, 0]],
665
+ metadata: [
595
666
  {
596
667
  details: { color: 'red', size: 'large' },
597
668
  category: 'clothing',
598
669
  },
599
670
  ],
600
- );
671
+ });
601
672
 
602
- const results = await vectorDB.query(indexName, [1, 0.1, 0], 10, {
603
- details: { $contains: { color: 'red' } },
673
+ const results = await vectorDB.query({
674
+ indexName,
675
+ queryVector: [1, 0.1, 0],
676
+ filter: { details: { $contains: { color: 'red' } } },
604
677
  });
605
678
  expect(results.length).toBeGreaterThan(0);
606
679
  results.forEach(result => {
@@ -610,37 +683,47 @@ describe('PgVector', () => {
610
683
 
611
684
  // String Pattern Tests
612
685
  it('should handle exact string matches', async () => {
613
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
614
- category: 'electronics',
686
+ const results = await vectorDB.query({
687
+ indexName,
688
+ queryVector: [1, 0, 0],
689
+ filter: { category: 'electronics' },
615
690
  });
616
691
  expect(results).toHaveLength(2);
617
692
  });
618
693
 
619
694
  it('should handle case-sensitive string matches', async () => {
620
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
621
- category: 'ELECTRONICS',
695
+ const results = await vectorDB.query({
696
+ indexName,
697
+ queryVector: [1, 0, 0],
698
+ filter: { category: 'ELECTRONICS' },
622
699
  });
623
700
  expect(results).toHaveLength(0);
624
701
  });
625
702
  it('should filter arrays by size', async () => {
626
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
627
- ratings: { $size: 3 },
703
+ const results = await vectorDB.query({
704
+ indexName,
705
+ queryVector: [1, 0, 0],
706
+ filter: { ratings: { $size: 3 } },
628
707
  });
629
708
  expect(results.length).toBeGreaterThan(0);
630
709
  results.forEach(result => {
631
710
  expect(result.metadata?.ratings).toHaveLength(3);
632
711
  });
633
712
 
634
- const noResults = await vectorDB.query(indexName, [1, 0, 0], 10, {
635
- ratings: { $size: 10 },
713
+ const noResults = await vectorDB.query({
714
+ indexName,
715
+ queryVector: [1, 0, 0],
716
+ filter: { ratings: { $size: 10 } },
636
717
  });
637
718
  expect(noResults).toHaveLength(0);
638
719
  });
639
720
 
640
721
  it('should handle $size with nested arrays', async () => {
641
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ nested: { array: [1, 2, 3, 4] } }]);
642
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
643
- 'nested.array': { $size: 4 },
722
+ await vectorDB.upsert({ indexName, vectors: [[1, 0.1, 0]], metadata: [{ nested: { array: [1, 2, 3, 4] } }] });
723
+ const results = await vectorDB.query({
724
+ indexName,
725
+ queryVector: [1, 0, 0],
726
+ filter: { 'nested.array': { $size: 4 } },
644
727
  });
645
728
  expect(results.length).toBeGreaterThan(0);
646
729
  results.forEach(result => {
@@ -652,8 +735,10 @@ describe('PgVector', () => {
652
735
  // Logical Operator Tests
653
736
  describe('Logical Operators', () => {
654
737
  it('should handle AND filter conditions', async () => {
655
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
656
- $and: [{ category: { $eq: 'electronics' } }, { price: { $gt: 75 } }],
738
+ const results = await vectorDB.query({
739
+ indexName,
740
+ queryVector: [1, 0, 0],
741
+ filter: { $and: [{ category: { $eq: 'electronics' } }, { price: { $gt: 75 } }] },
657
742
  });
658
743
  expect(results).toHaveLength(1);
659
744
  expect(results[0]?.metadata?.category).toBe('electronics');
@@ -661,8 +746,10 @@ describe('PgVector', () => {
661
746
  });
662
747
 
663
748
  it('should handle OR filter conditions', async () => {
664
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
665
- $or: [{ category: { $eq: 'electronics' } }, { category: { $eq: 'books' } }],
749
+ const results = await vectorDB.query({
750
+ indexName,
751
+ queryVector: [1, 0, 0],
752
+ filter: { $or: [{ category: { $eq: 'electronics' } }, { category: { $eq: 'books' } }] },
666
753
  });
667
754
  expect(results.length).toBeGreaterThan(1);
668
755
  results.forEach(result => {
@@ -671,8 +758,10 @@ describe('PgVector', () => {
671
758
  });
672
759
 
673
760
  it('should handle $not operator', async () => {
674
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
675
- $not: { category: 'electronics' },
761
+ const results = await vectorDB.query({
762
+ indexName,
763
+ queryVector: [1, 0, 0],
764
+ filter: { $not: { category: 'electronics' } },
676
765
  });
677
766
  expect(results.length).toBeGreaterThan(0);
678
767
  results.forEach(result => {
@@ -681,8 +770,10 @@ describe('PgVector', () => {
681
770
  });
682
771
 
683
772
  it('should handle $nor operator', async () => {
684
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
685
- $nor: [{ category: 'electronics' }, { category: 'books' }],
773
+ const results = await vectorDB.query({
774
+ indexName,
775
+ queryVector: [1, 0, 0],
776
+ filter: { $nor: [{ category: 'electronics' }, { category: 'books' }] },
686
777
  });
687
778
  expect(results.length).toBeGreaterThan(0);
688
779
  results.forEach(result => {
@@ -691,8 +782,10 @@ describe('PgVector', () => {
691
782
  });
692
783
 
693
784
  it('should handle nested $not with $or', async () => {
694
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
695
- $not: { $or: [{ category: 'electronics' }, { category: 'books' }] },
785
+ const results = await vectorDB.query({
786
+ indexName,
787
+ queryVector: [1, 0, 0],
788
+ filter: { $not: { $or: [{ category: 'electronics' }, { category: 'books' }] } },
696
789
  });
697
790
  expect(results.length).toBeGreaterThan(0);
698
791
  results.forEach(result => {
@@ -701,8 +794,10 @@ describe('PgVector', () => {
701
794
  });
702
795
 
703
796
  it('should handle $not with comparison operators', async () => {
704
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
705
- price: { $not: { $gt: 100 } },
797
+ const results = await vectorDB.query({
798
+ indexName,
799
+ queryVector: [1, 0, 0],
800
+ filter: { price: { $not: { $gt: 100 } } },
706
801
  });
707
802
  expect(results.length).toBeGreaterThan(0);
708
803
  results.forEach(result => {
@@ -711,8 +806,10 @@ describe('PgVector', () => {
711
806
  });
712
807
 
713
808
  it('should handle $not with $in operator', async () => {
714
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
715
- category: { $not: { $in: ['electronics', 'books'] } },
809
+ const results = await vectorDB.query({
810
+ indexName,
811
+ queryVector: [1, 0, 0],
812
+ filter: { category: { $not: { $in: ['electronics', 'books'] } } },
716
813
  });
717
814
  expect(results.length).toBeGreaterThan(0);
718
815
  results.forEach(result => {
@@ -721,8 +818,10 @@ describe('PgVector', () => {
721
818
  });
722
819
 
723
820
  it('should handle $not with multiple nested conditions', async () => {
724
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
725
- $not: { $and: [{ category: 'electronics' }, { price: { $gt: 50 } }] },
821
+ const results = await vectorDB.query({
822
+ indexName,
823
+ queryVector: [1, 0, 0],
824
+ filter: { $not: { $and: [{ category: 'electronics' }, { price: { $gt: 50 } }] } },
726
825
  });
727
826
  expect(results.length).toBeGreaterThan(0);
728
827
  results.forEach(result => {
@@ -731,15 +830,19 @@ describe('PgVector', () => {
731
830
  });
732
831
 
733
832
  it('should handle $not with $exists operator', async () => {
734
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
735
- tags: { $not: { $exists: true } },
833
+ const results = await vectorDB.query({
834
+ indexName,
835
+ queryVector: [1, 0, 0],
836
+ filter: { tags: { $not: { $exists: true } } },
736
837
  });
737
838
  expect(results.length).toBe(0); // All test data has tags
738
839
  });
739
840
 
740
841
  it('should handle $not with array operators', async () => {
741
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
742
- tags: { $not: { $all: ['new', 'premium'] } },
842
+ const results = await vectorDB.query({
843
+ indexName,
844
+ queryVector: [1, 0, 0],
845
+ filter: { tags: { $not: { $all: ['new', 'premium'] } } },
743
846
  });
744
847
  expect(results.length).toBeGreaterThan(0);
745
848
  results.forEach(result => {
@@ -748,16 +851,20 @@ describe('PgVector', () => {
748
851
  });
749
852
 
750
853
  it('should handle $not with complex nested conditions', async () => {
751
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
752
- $not: {
753
- $or: [
754
- {
755
- $and: [{ category: 'electronics' }, { price: { $gt: 90 } }],
756
- },
757
- {
758
- $and: [{ category: 'books' }, { price: { $lt: 30 } }],
759
- },
760
- ],
854
+ const results = await vectorDB.query({
855
+ indexName,
856
+ queryVector: [1, 0, 0],
857
+ filter: {
858
+ $not: {
859
+ $or: [
860
+ {
861
+ $and: [{ category: 'electronics' }, { price: { $gt: 90 } }],
862
+ },
863
+ {
864
+ $and: [{ category: 'books' }, { price: { $lt: 30 } }],
865
+ },
866
+ ],
867
+ },
761
868
  },
762
869
  });
763
870
  expect(results.length).toBeGreaterThan(0);
@@ -769,18 +876,26 @@ describe('PgVector', () => {
769
876
  });
770
877
 
771
878
  it('should handle $not with empty arrays', async () => {
772
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
773
- tags: { $not: { $in: [] } },
879
+ const results = await vectorDB.query({
880
+ indexName,
881
+ queryVector: [1, 0, 0],
882
+ filter: { tags: { $not: { $in: [] } } },
774
883
  });
775
884
  expect(results.length).toBeGreaterThan(0); // Should match all records
776
885
  });
777
886
 
778
887
  it('should handle $not with null values', async () => {
779
888
  // First insert a record with null value
780
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ category: null, price: 0 }]);
889
+ await vectorDB.upsert({
890
+ indexName,
891
+ vectors: [[1, 0.1, 0]],
892
+ metadata: [{ category: null, price: 0 }],
893
+ });
781
894
 
782
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
783
- category: { $not: { $eq: null } },
895
+ const results = await vectorDB.query({
896
+ indexName,
897
+ queryVector: [1, 0, 0],
898
+ filter: { category: { $not: { $eq: null } } },
784
899
  });
785
900
  expect(results.length).toBeGreaterThan(0);
786
901
  results.forEach(result => {
@@ -789,8 +904,10 @@ describe('PgVector', () => {
789
904
  });
790
905
 
791
906
  it('should handle $not with boolean values', async () => {
792
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
793
- active: { $not: { $eq: true } },
907
+ const results = await vectorDB.query({
908
+ indexName,
909
+ queryVector: [1, 0, 0],
910
+ filter: { active: { $not: { $eq: true } } },
794
911
  });
795
912
  expect(results.length).toBeGreaterThan(0);
796
913
  results.forEach(result => {
@@ -799,30 +916,42 @@ describe('PgVector', () => {
799
916
  });
800
917
 
801
918
  it('should handle $not with multiple conditions', async () => {
802
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
803
- $not: { category: 'electronics', price: { $gt: 50 } },
919
+ const results = await vectorDB.query({
920
+ indexName,
921
+ queryVector: [1, 0, 0],
922
+ filter: { $not: { category: 'electronics', price: { $gt: 50 } } },
804
923
  });
805
924
  expect(results.length).toBeGreaterThan(0);
806
925
  });
807
926
 
808
927
  it('should handle $not with $not operator', async () => {
809
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
810
- $not: { $not: { category: 'electronics' } },
928
+ const results = await vectorDB.query({
929
+ indexName,
930
+ queryVector: [1, 0, 0],
931
+ filter: { $not: { $not: { category: 'electronics' } } },
811
932
  });
812
933
  expect(results.length).toBeGreaterThan(0);
813
934
  });
814
935
 
815
936
  it('should handle $not in nested fields', async () => {
816
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ user: { profile: { price: 10 } } }]);
817
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
818
- 'user.profile.price': { $not: { $gt: 25 } },
937
+ await vectorDB.upsert({
938
+ indexName,
939
+ vectors: [[1, 0.1, 0]],
940
+ metadata: [{ user: { profile: { price: 10 } } }],
941
+ });
942
+ const results = await vectorDB.query({
943
+ indexName,
944
+ queryVector: [1, 0, 0],
945
+ filter: { 'user.profile.price': { $not: { $gt: 25 } } },
819
946
  });
820
947
  expect(results.length).toBe(1);
821
948
  });
822
949
 
823
950
  it('should handle $not with multiple operators', async () => {
824
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
825
- price: { $not: { $gte: 30, $lte: 70 } },
951
+ const results = await vectorDB.query({
952
+ indexName,
953
+ queryVector: [1, 0, 0],
954
+ filter: { price: { $not: { $gte: 30, $lte: 70 } } },
826
955
  });
827
956
  expect(results.length).toBeGreaterThan(0);
828
957
  results.forEach(result => {
@@ -832,8 +961,10 @@ describe('PgVector', () => {
832
961
  });
833
962
 
834
963
  it('should handle $not with comparison operators', async () => {
835
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
836
- price: { $not: { $gt: 100 } },
964
+ const results = await vectorDB.query({
965
+ indexName,
966
+ queryVector: [1, 0, 0],
967
+ filter: { price: { $not: { $gt: 100 } } },
837
968
  });
838
969
  expect(results.length).toBeGreaterThan(0);
839
970
  results.forEach(result => {
@@ -842,10 +973,10 @@ describe('PgVector', () => {
842
973
  });
843
974
 
844
975
  it('should handle $not with $and', async () => {
845
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
846
- $not: {
847
- $and: [{ category: 'electronics' }, { price: { $gt: 50 } }],
848
- },
976
+ const results = await vectorDB.query({
977
+ indexName,
978
+ queryVector: [1, 0, 0],
979
+ filter: { $not: { $and: [{ category: 'electronics' }, { price: { $gt: 50 } }] } },
849
980
  });
850
981
  expect(results.length).toBeGreaterThan(0);
851
982
  results.forEach(result => {
@@ -854,8 +985,10 @@ describe('PgVector', () => {
854
985
  });
855
986
 
856
987
  it('should handle $nor with $or', async () => {
857
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
858
- $nor: [{ $or: [{ category: 'electronics' }, { category: 'books' }] }, { price: { $gt: 75 } }],
988
+ const results = await vectorDB.query({
989
+ indexName,
990
+ queryVector: [1, 0, 0],
991
+ filter: { $nor: [{ $or: [{ category: 'electronics' }, { category: 'books' }] }, { price: { $gt: 75 } }] },
859
992
  });
860
993
  expect(results.length).toBeGreaterThan(0);
861
994
  results.forEach(result => {
@@ -865,11 +998,15 @@ describe('PgVector', () => {
865
998
  });
866
999
 
867
1000
  it('should handle $nor with nested $and conditions', async () => {
868
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
869
- $nor: [
870
- { $and: [{ category: 'electronics' }, { active: true }] },
871
- { $and: [{ category: 'books' }, { price: { $lt: 30 } }] },
872
- ],
1001
+ const results = await vectorDB.query({
1002
+ indexName,
1003
+ queryVector: [1, 0, 0],
1004
+ filter: {
1005
+ $nor: [
1006
+ { $and: [{ category: 'electronics' }, { active: true }] },
1007
+ { $and: [{ category: 'books' }, { price: { $lt: 30 } }] },
1008
+ ],
1009
+ },
873
1010
  });
874
1011
  expect(results.length).toBeGreaterThan(0);
875
1012
  results.forEach(result => {
@@ -882,8 +1019,12 @@ describe('PgVector', () => {
882
1019
  });
883
1020
 
884
1021
  it('should handle nested $and with $or and $not', async () => {
885
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
886
- $and: [{ $or: [{ category: 'electronics' }, { category: 'books' }] }, { $not: { price: { $lt: 50 } } }],
1022
+ const results = await vectorDB.query({
1023
+ indexName,
1024
+ queryVector: [1, 0, 0],
1025
+ filter: {
1026
+ $and: [{ $or: [{ category: 'electronics' }, { category: 'books' }] }, { $not: { price: { $lt: 50 } } }],
1027
+ },
887
1028
  });
888
1029
  expect(results.length).toBeGreaterThan(0);
889
1030
  results.forEach(result => {
@@ -893,8 +1034,10 @@ describe('PgVector', () => {
893
1034
  });
894
1035
 
895
1036
  it('should handle $or with multiple $not conditions', async () => {
896
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
897
- $or: [{ $not: { category: 'electronics' } }, { $not: { price: { $gt: 50 } } }],
1037
+ const results = await vectorDB.query({
1038
+ indexName,
1039
+ queryVector: [1, 0, 0],
1040
+ filter: { $or: [{ $not: { category: 'electronics' } }, { $not: { price: { $gt: 50 } } }] },
898
1041
  });
899
1042
  expect(results.length).toBeGreaterThan(0);
900
1043
  results.forEach(result => {
@@ -906,29 +1049,43 @@ describe('PgVector', () => {
906
1049
  // Edge Cases and Special Values
907
1050
  describe('Edge Cases and Special Values', () => {
908
1051
  it('should handle empty result sets with valid filters', async () => {
909
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
910
- price: { $gt: 1000 },
1052
+ const results = await vectorDB.query({
1053
+ indexName,
1054
+ queryVector: [1, 0, 0],
1055
+ filter: { price: { $gt: 1000 } },
911
1056
  });
912
1057
  expect(results).toHaveLength(0);
913
1058
  });
914
1059
 
915
1060
  it('should throw error for invalid operator', async () => {
916
1061
  await expect(
917
- vectorDB.query(indexName, [1, 0, 0], 10, {
918
- price: { $invalid: 100 },
1062
+ vectorDB.query({
1063
+ indexName,
1064
+ queryVector: [1, 0, 0],
1065
+ filter: { price: { $invalid: 100 } },
919
1066
  }),
920
1067
  ).rejects.toThrow('Unsupported operator: $invalid');
921
1068
  });
922
1069
 
923
1070
  it('should handle empty filter object', async () => {
924
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {});
1071
+ const results = await vectorDB.query({
1072
+ indexName,
1073
+ queryVector: [1, 0, 0],
1074
+ filter: {},
1075
+ });
925
1076
  expect(results.length).toBeGreaterThan(0);
926
1077
  });
927
1078
 
928
1079
  it('should handle numeric string comparisons', async () => {
929
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ numericString: '123' }]);
930
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
931
- numericString: { $gt: '100' },
1080
+ await vectorDB.upsert({
1081
+ indexName,
1082
+ vectors: [[1, 0.1, 0]],
1083
+ metadata: [{ numericString: '123' }],
1084
+ });
1085
+ const results = await vectorDB.query({
1086
+ indexName,
1087
+ queryVector: [1, 0, 0],
1088
+ filter: { numericString: { $gt: '100' } },
932
1089
  });
933
1090
  expect(results.length).toBeGreaterThan(0);
934
1091
  expect(results[0]?.metadata?.numericString).toBe('123');
@@ -938,7 +1095,12 @@ describe('PgVector', () => {
938
1095
  // Score Threshold Tests
939
1096
  describe('Score Threshold', () => {
940
1097
  it('should respect minimum score threshold', async () => {
941
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, { category: 'electronics' }, false, 0.9);
1098
+ const results = await vectorDB.query({
1099
+ indexName,
1100
+ queryVector: [1, 0, 0],
1101
+ filter: { category: 'electronics' },
1102
+ minScore: 0.9,
1103
+ });
942
1104
  expect(results.length).toBeGreaterThan(0);
943
1105
  results.forEach(result => {
944
1106
  expect(result.score).toBeGreaterThan(0.9);
@@ -949,43 +1111,46 @@ describe('PgVector', () => {
949
1111
  describe('Edge Cases and Special Values', () => {
950
1112
  // Additional Edge Cases
951
1113
  it('should handle empty result sets with valid filters', async () => {
952
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
953
- price: { $gt: 1000 },
1114
+ const results = await vectorDB.query({
1115
+ indexName,
1116
+ queryVector: [1, 0, 0],
1117
+ filter: { price: { $gt: 1000 } },
954
1118
  });
955
1119
  expect(results).toHaveLength(0);
956
1120
  });
957
1121
 
958
1122
  it('should handle empty filter object', async () => {
959
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {});
1123
+ const results = await vectorDB.query({
1124
+ indexName,
1125
+ queryVector: [1, 0, 0],
1126
+ filter: {},
1127
+ });
960
1128
  expect(results.length).toBeGreaterThan(0);
961
1129
  });
962
1130
 
963
1131
  it('should handle non-existent field', async () => {
964
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
965
- nonexistent: {
966
- $elemMatch: {
967
- $eq: 'value',
968
- },
969
- },
1132
+ const results = await vectorDB.query({
1133
+ indexName,
1134
+ queryVector: [1, 0, 0],
1135
+ filter: { nonexistent: { $elemMatch: { $eq: 'value' } } },
970
1136
  });
971
1137
  expect(results).toHaveLength(0);
972
1138
  });
973
1139
 
974
1140
  it('should handle non-existent values', async () => {
975
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
976
- tags: {
977
- $elemMatch: {
978
- $eq: 'nonexistent-tag',
979
- },
980
- },
1141
+ const results = await vectorDB.query({
1142
+ indexName,
1143
+ queryVector: [1, 0, 0],
1144
+ filter: { tags: { $elemMatch: { $eq: 'nonexistent-tag' } } },
981
1145
  });
982
1146
  expect(results).toHaveLength(0);
983
1147
  });
984
1148
  // Empty Conditions Tests
985
1149
  it('should handle empty conditions in logical operators', async () => {
986
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
987
- $and: [],
988
- category: 'electronics',
1150
+ const results = await vectorDB.query({
1151
+ indexName,
1152
+ queryVector: [1, 0, 0],
1153
+ filter: { $and: [], category: 'electronics' },
989
1154
  });
990
1155
  expect(results.length).toBeGreaterThan(0);
991
1156
  results.forEach(result => {
@@ -994,9 +1159,10 @@ describe('PgVector', () => {
994
1159
  });
995
1160
 
996
1161
  it('should handle empty $and conditions', async () => {
997
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
998
- $and: [],
999
- category: 'electronics',
1162
+ const results = await vectorDB.query({
1163
+ indexName,
1164
+ queryVector: [1, 0, 0],
1165
+ filter: { $and: [], category: 'electronics' },
1000
1166
  });
1001
1167
  expect(results.length).toBeGreaterThan(0);
1002
1168
  results.forEach(result => {
@@ -1005,17 +1171,19 @@ describe('PgVector', () => {
1005
1171
  });
1006
1172
 
1007
1173
  it('should handle empty $or conditions', async () => {
1008
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1009
- $or: [],
1010
- category: 'electronics',
1174
+ const results = await vectorDB.query({
1175
+ indexName,
1176
+ queryVector: [1, 0, 0],
1177
+ filter: { $or: [], category: 'electronics' },
1011
1178
  });
1012
1179
  expect(results).toHaveLength(0);
1013
1180
  });
1014
1181
 
1015
1182
  it('should handle empty $nor conditions', async () => {
1016
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1017
- $nor: [],
1018
- category: 'electronics',
1183
+ const results = await vectorDB.query({
1184
+ indexName,
1185
+ queryVector: [1, 0, 0],
1186
+ filter: { $nor: [], category: 'electronics' },
1019
1187
  });
1020
1188
  expect(results.length).toBeGreaterThan(0);
1021
1189
  results.forEach(result => {
@@ -1025,29 +1193,29 @@ describe('PgVector', () => {
1025
1193
 
1026
1194
  it('should handle empty $not conditions', async () => {
1027
1195
  await expect(
1028
- vectorDB.query(indexName, [1, 0, 0], 10, {
1029
- $not: {},
1030
- category: 'electronics',
1196
+ vectorDB.query({
1197
+ indexName,
1198
+ queryVector: [1, 0, 0],
1199
+ filter: { $not: {}, category: 'electronics' },
1031
1200
  }),
1032
1201
  ).rejects.toThrow('$not operator cannot be empty');
1033
1202
  });
1034
1203
 
1035
1204
  it('should handle multiple empty logical operators', async () => {
1036
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1037
- $and: [],
1038
- $or: [],
1039
- $nor: [],
1040
- category: 'electronics',
1205
+ const results = await vectorDB.query({
1206
+ indexName,
1207
+ queryVector: [1, 0, 0],
1208
+ filter: { $and: [], $or: [], $nor: [], category: 'electronics' },
1041
1209
  });
1042
1210
  expect(results).toHaveLength(0);
1043
1211
  });
1044
1212
 
1045
1213
  // Nested Field Tests
1046
1214
  it('should handle deeply nested metadata paths', async () => {
1047
- await vectorDB.upsert(
1215
+ await vectorDB.upsert({
1048
1216
  indexName,
1049
- [[1, 0.1, 0]],
1050
- [
1217
+ vectors: [[1, 0.1, 0]],
1218
+ metadata: [
1051
1219
  {
1052
1220
  level1: {
1053
1221
  level2: {
@@ -1056,32 +1224,34 @@ describe('PgVector', () => {
1056
1224
  },
1057
1225
  },
1058
1226
  ],
1059
- );
1227
+ });
1060
1228
 
1061
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1062
- 'level1.level2.level3': 'deep value',
1229
+ const results = await vectorDB.query({
1230
+ indexName,
1231
+ queryVector: [1, 0, 0],
1232
+ filter: { 'level1.level2.level3': 'deep value' },
1063
1233
  });
1064
1234
  expect(results).toHaveLength(1);
1065
1235
  expect(results[0]?.metadata?.level1?.level2?.level3).toBe('deep value');
1066
1236
  });
1067
1237
 
1068
1238
  it('should handle non-existent nested paths', async () => {
1069
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1070
- 'nonexistent.path': 'value',
1239
+ const results = await vectorDB.query({
1240
+ indexName,
1241
+ queryVector: [1, 0, 0],
1242
+ filter: { 'nonexistent.path': 'value' },
1071
1243
  });
1072
1244
  expect(results).toHaveLength(0);
1073
1245
  });
1074
1246
 
1075
1247
  // Score Threshold Tests
1076
1248
  it('should respect minimum score threshold', async () => {
1077
- const results = await vectorDB.query(
1078
- indexName,
1079
- [1, 0, 0],
1080
- 10,
1081
- { category: 'electronics' },
1082
- false,
1083
- 0.9, // minScore
1084
- );
1249
+ const results = await vectorDB.query({
1250
+ indexName,
1251
+ queryVector: [1, 0, 0],
1252
+ filter: { category: 'electronics' },
1253
+ minScore: 0.9, // minScore
1254
+ });
1085
1255
  expect(results.length).toBeGreaterThan(0);
1086
1256
  results.forEach(result => {
1087
1257
  expect(result.score).toBeGreaterThan(0.9);
@@ -1090,17 +1260,21 @@ describe('PgVector', () => {
1090
1260
 
1091
1261
  // Complex Nested Operators Test
1092
1262
  it('should handle deeply nested logical operators', async () => {
1093
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1094
- $and: [
1095
- {
1096
- $or: [{ category: 'electronics' }, { $and: [{ category: 'books' }, { price: { $lt: 30 } }] }],
1097
- },
1098
- {
1099
- $not: {
1100
- $or: [{ active: false }, { price: { $gt: 100 } }],
1263
+ const results = await vectorDB.query({
1264
+ indexName,
1265
+ queryVector: [1, 0, 0],
1266
+ filter: {
1267
+ $and: [
1268
+ {
1269
+ $or: [{ category: 'electronics' }, { $and: [{ category: 'books' }, { price: { $lt: 30 } }] }],
1101
1270
  },
1102
- },
1103
- ],
1271
+ {
1272
+ $not: {
1273
+ $or: [{ active: false }, { price: { $gt: 100 } }],
1274
+ },
1275
+ },
1276
+ ],
1277
+ },
1104
1278
  });
1105
1279
  expect(results.length).toBeGreaterThan(0);
1106
1280
  results.forEach(result => {
@@ -1118,16 +1292,19 @@ describe('PgVector', () => {
1118
1292
 
1119
1293
  it('should throw error for invalid operator', async () => {
1120
1294
  await expect(
1121
- vectorDB.query(indexName, [1, 0, 0], 10, {
1122
- price: { $invalid: 100 },
1295
+ vectorDB.query({
1296
+ indexName,
1297
+ queryVector: [1, 0, 0],
1298
+ filter: { price: { $invalid: 100 } },
1123
1299
  }),
1124
1300
  ).rejects.toThrow('Unsupported operator: $invalid');
1125
1301
  });
1126
1302
 
1127
1303
  it('should handle multiple logical operators at root level', async () => {
1128
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1129
- $and: [{ category: 'electronics' }],
1130
- $or: [{ price: { $lt: 100 } }, { price: { $gt: 20 } }],
1304
+ const results = await vectorDB.query({
1305
+ indexName,
1306
+ queryVector: [1, 0, 0],
1307
+ filter: { $and: [{ category: 'electronics' }], $or: [{ price: { $lt: 100 } }, { price: { $gt: 20 } }] },
1131
1308
  });
1132
1309
  expect(results.length).toBeGreaterThan(0);
1133
1310
  results.forEach(result => {
@@ -1138,34 +1315,63 @@ describe('PgVector', () => {
1138
1315
 
1139
1316
  it('should handle non-array field with $elemMatch', async () => {
1140
1317
  // First insert a record with non-array field
1141
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ tags: 'not-an-array' }]);
1318
+ await vectorDB.upsert({
1319
+ indexName,
1320
+ vectors: [[1, 0.1, 0]],
1321
+ metadata: [{ tags: 'not-an-array' }],
1322
+ });
1142
1323
 
1143
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1144
- tags: {
1145
- $elemMatch: {
1146
- $eq: 'value',
1324
+ const results = await vectorDB.query({
1325
+ indexName,
1326
+ queryVector: [1, 0, 0],
1327
+ filter: {
1328
+ tags: {
1329
+ $elemMatch: {
1330
+ $eq: 'value',
1331
+ },
1147
1332
  },
1148
1333
  },
1149
1334
  });
1150
1335
  expect(results).toHaveLength(0); // Should return no results for non-array field
1151
1336
  });
1152
1337
  it('should handle undefined filter', async () => {
1153
- const results1 = await vectorDB.query(indexName, [1, 0, 0], 10, undefined);
1154
- const results2 = await vectorDB.query(indexName, [1, 0, 0], 10);
1338
+ const results1 = await vectorDB.query({
1339
+ indexName,
1340
+ queryVector: [1, 0, 0],
1341
+ filter: undefined,
1342
+ });
1343
+ const results2 = await vectorDB.query({
1344
+ indexName,
1345
+ queryVector: [1, 0, 0],
1346
+ });
1155
1347
  expect(results1).toEqual(results2);
1156
1348
  expect(results1.length).toBeGreaterThan(0);
1157
1349
  });
1158
1350
 
1159
1351
  it('should handle empty object filter', async () => {
1160
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {});
1161
- const results2 = await vectorDB.query(indexName, [1, 0, 0], 10);
1352
+ const results = await vectorDB.query({
1353
+ indexName,
1354
+ queryVector: [1, 0, 0],
1355
+ filter: {},
1356
+ });
1357
+ const results2 = await vectorDB.query({
1358
+ indexName,
1359
+ queryVector: [1, 0, 0],
1360
+ });
1162
1361
  expect(results).toEqual(results2);
1163
1362
  expect(results.length).toBeGreaterThan(0);
1164
1363
  });
1165
1364
 
1166
1365
  it('should handle null filter', async () => {
1167
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, null as any);
1168
- const results2 = await vectorDB.query(indexName, [1, 0, 0], 10);
1366
+ const results = await vectorDB.query({
1367
+ indexName,
1368
+ queryVector: [1, 0, 0],
1369
+ filter: null,
1370
+ });
1371
+ const results2 = await vectorDB.query({
1372
+ indexName,
1373
+ queryVector: [1, 0, 0],
1374
+ });
1169
1375
  expect(results).toEqual(results2);
1170
1376
  expect(results.length).toBeGreaterThan(0);
1171
1377
  });
@@ -1174,58 +1380,82 @@ describe('PgVector', () => {
1174
1380
  // Regex Operator Tests
1175
1381
  describe('Regex Operators', () => {
1176
1382
  it('should handle $regex with case sensitivity', async () => {
1177
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1178
- category: { $regex: 'ELECTRONICS' },
1383
+ const results = await vectorDB.query({
1384
+ indexName,
1385
+ queryVector: [1, 0, 0],
1386
+ filter: { category: { $regex: 'ELECTRONICS' } },
1179
1387
  });
1180
1388
  expect(results).toHaveLength(0);
1181
1389
  });
1182
1390
 
1183
1391
  it('should handle $regex with case insensitivity', async () => {
1184
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1185
- category: { $regex: 'ELECTRONICS', $options: 'i' },
1392
+ const results = await vectorDB.query({
1393
+ indexName,
1394
+ queryVector: [1, 0, 0],
1395
+ filter: { category: { $regex: 'ELECTRONICS', $options: 'i' } },
1186
1396
  });
1187
1397
  expect(results).toHaveLength(2);
1188
1398
  });
1189
1399
 
1190
1400
  it('should handle $regex with start anchor', async () => {
1191
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1192
- category: { $regex: '^elect' },
1401
+ const results = await vectorDB.query({
1402
+ indexName,
1403
+ queryVector: [1, 0, 0],
1404
+ filter: { category: { $regex: '^elect' } },
1193
1405
  });
1194
1406
  expect(results).toHaveLength(2);
1195
1407
  });
1196
1408
 
1197
1409
  it('should handle $regex with end anchor', async () => {
1198
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1199
- category: { $regex: 'nics$' },
1410
+ const results = await vectorDB.query({
1411
+ indexName,
1412
+ queryVector: [1, 0, 0],
1413
+ filter: { category: { $regex: 'nics$' } },
1200
1414
  });
1201
1415
  expect(results).toHaveLength(2);
1202
1416
  });
1203
1417
 
1204
1418
  it('should handle multiline flag', async () => {
1205
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ description: 'First line\nSecond line\nThird line' }]);
1419
+ await vectorDB.upsert({
1420
+ indexName,
1421
+ vectors: [[1, 0.1, 0]],
1422
+ metadata: [{ description: 'First line\nSecond line\nThird line' }],
1423
+ });
1206
1424
 
1207
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1208
- description: { $regex: '^Second', $options: 'm' },
1425
+ const results = await vectorDB.query({
1426
+ indexName,
1427
+ queryVector: [1, 0, 0],
1428
+ filter: { description: { $regex: '^Second', $options: 'm' } },
1209
1429
  });
1210
1430
  expect(results).toHaveLength(1);
1211
1431
  });
1212
1432
 
1213
1433
  it('should handle dotall flag', async () => {
1214
- await vectorDB.upsert(indexName, [[1, 0.1, 0]], [{ description: 'First\nSecond\nThird' }]);
1434
+ await vectorDB.upsert({
1435
+ indexName,
1436
+ vectors: [[1, 0.1, 0]],
1437
+ metadata: [{ description: 'First\nSecond\nThird' }],
1438
+ });
1215
1439
 
1216
- const withoutS = await vectorDB.query(indexName, [1, 0, 0], 10, {
1217
- description: { $regex: 'First[^\\n]*Third' },
1440
+ const withoutS = await vectorDB.query({
1441
+ indexName,
1442
+ queryVector: [1, 0, 0],
1443
+ filter: { description: { $regex: 'First[^\\n]*Third' } },
1218
1444
  });
1219
1445
  expect(withoutS).toHaveLength(0);
1220
1446
 
1221
- const withS = await vectorDB.query(indexName, [1, 0, 0], 10, {
1222
- description: { $regex: 'First.*Third', $options: 's' },
1447
+ const withS = await vectorDB.query({
1448
+ indexName,
1449
+ queryVector: [1, 0, 0],
1450
+ filter: { description: { $regex: 'First.*Third', $options: 's' } },
1223
1451
  });
1224
1452
  expect(withS).toHaveLength(1);
1225
1453
  });
1226
1454
  it('should handle $not with $regex operator', async () => {
1227
- const results = await vectorDB.query(indexName, [1, 0, 0], 10, {
1228
- category: { $not: { $regex: '^elect' } },
1455
+ const results = await vectorDB.query({
1456
+ indexName,
1457
+ queryVector: [1, 0, 0],
1458
+ filter: { category: { $not: { $regex: '^elect' } } },
1229
1459
  });
1230
1460
  expect(results.length).toBeGreaterThan(0);
1231
1461
  results.forEach(result => {
@@ -1245,11 +1475,19 @@ describe('PgVector', () => {
1245
1475
 
1246
1476
  describe('HNSW Parameters', () => {
1247
1477
  beforeAll(async () => {
1248
- await vectorDB.createIndex(indexName, 3, 'cosine', {
1249
- type: 'hnsw',
1250
- hnsw: { m: 16, efConstruction: 64 },
1478
+ await vectorDB.createIndex({
1479
+ indexName,
1480
+ dimension: 3,
1481
+ metric: 'cosine',
1482
+ indexConfig: {
1483
+ type: 'hnsw',
1484
+ hnsw: { m: 16, efConstruction: 64 },
1485
+ },
1486
+ });
1487
+ await vectorDB.upsert({
1488
+ indexName,
1489
+ vectors,
1251
1490
  });
1252
- await vectorDB.upsert(indexName, vectors);
1253
1491
  });
1254
1492
 
1255
1493
  afterAll(async () => {
@@ -1257,14 +1495,23 @@ describe('PgVector', () => {
1257
1495
  });
1258
1496
 
1259
1497
  it('should use default ef value', async () => {
1260
- const results = await vectorDB.query(indexName, [1, 0, 0], 2);
1498
+ const results = await vectorDB.query({
1499
+ indexName,
1500
+ queryVector: [1, 0, 0],
1501
+ topK: 2,
1502
+ });
1261
1503
  expect(results).toHaveLength(2);
1262
1504
  expect(results[0]?.score).toBeCloseTo(1, 5);
1263
1505
  expect(results[1]?.score).toBeGreaterThan(0.9); // Second vector should be close
1264
1506
  });
1265
1507
 
1266
1508
  it('should respect custom ef value', async () => {
1267
- const results = await vectorDB.query(indexName, [1, 0, 0], 2, undefined, undefined, undefined, { ef: 100 });
1509
+ const results = await vectorDB.query({
1510
+ indexName,
1511
+ queryVector: [1, 0, 0],
1512
+ topK: 2,
1513
+ ef: 100,
1514
+ });
1268
1515
  expect(results).toHaveLength(2);
1269
1516
  expect(results[0]?.score).toBeCloseTo(1, 5);
1270
1517
  expect(results[1]?.score).toBeGreaterThan(0.9);
@@ -1273,11 +1520,19 @@ describe('PgVector', () => {
1273
1520
 
1274
1521
  describe('IVF Parameters', () => {
1275
1522
  beforeAll(async () => {
1276
- await vectorDB.createIndex(indexName, 3, 'cosine', {
1277
- type: 'ivfflat',
1278
- ivf: { lists: 2 }, // Small number for test data
1523
+ await vectorDB.createIndex({
1524
+ indexName,
1525
+ dimension: 3,
1526
+ metric: 'cosine',
1527
+ indexConfig: {
1528
+ type: 'ivfflat',
1529
+ ivf: { lists: 2 }, // Small number for test data
1530
+ },
1531
+ });
1532
+ await vectorDB.upsert({
1533
+ indexName,
1534
+ vectors,
1279
1535
  });
1280
- await vectorDB.upsert(indexName, vectors);
1281
1536
  });
1282
1537
 
1283
1538
  afterAll(async () => {
@@ -1285,18 +1540,145 @@ describe('PgVector', () => {
1285
1540
  });
1286
1541
 
1287
1542
  it('should use default probe value', async () => {
1288
- const results = await vectorDB.query(indexName, [1, 0, 0], 2);
1543
+ const results = await vectorDB.query({
1544
+ indexName,
1545
+ queryVector: [1, 0, 0],
1546
+ topK: 2,
1547
+ });
1289
1548
  expect(results).toHaveLength(2);
1290
1549
  expect(results[0]?.score).toBeCloseTo(1, 5);
1291
1550
  expect(results[1]?.score).toBeGreaterThan(0.9);
1292
1551
  });
1293
1552
 
1294
1553
  it('should respect custom probe value', async () => {
1295
- const results = await vectorDB.query(indexName, [1, 0, 0], 2, undefined, undefined, undefined, { probes: 2 });
1554
+ const results = await vectorDB.query({
1555
+ indexName,
1556
+ queryVector: [1, 0, 0],
1557
+ topK: 2,
1558
+ probes: 2,
1559
+ });
1296
1560
  expect(results).toHaveLength(2);
1297
1561
  expect(results[0]?.score).toBeCloseTo(1, 5);
1298
1562
  expect(results[1]?.score).toBeGreaterThan(0.9);
1299
1563
  });
1300
1564
  });
1301
1565
  });
1566
+ describe('Deprecation Warnings', () => {
1567
+ const indexName = 'testdeprecationwarnings';
1568
+
1569
+ const indexName2 = 'testdeprecationwarnings2';
1570
+
1571
+ let warnSpy;
1572
+
1573
+ beforeAll(async () => {
1574
+ await vectorDB.createIndex({ indexName: indexName, dimension: 3 });
1575
+ });
1576
+
1577
+ afterAll(async () => {
1578
+ await vectorDB.deleteIndex(indexName);
1579
+ await vectorDB.deleteIndex(indexName2);
1580
+ });
1581
+
1582
+ beforeEach(async () => {
1583
+ warnSpy = vi.spyOn(vectorDB['logger'], 'warn');
1584
+ });
1585
+
1586
+ afterEach(async () => {
1587
+ warnSpy.mockRestore();
1588
+ await vectorDB.deleteIndex(indexName2);
1589
+ });
1590
+
1591
+ it('should show deprecation warning when using individual args for createIndex', async () => {
1592
+ await vectorDB.createIndex(indexName2, 3, 'cosine');
1593
+
1594
+ expect(warnSpy).toHaveBeenCalledWith(
1595
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to createIndex() is deprecated'),
1596
+ );
1597
+ });
1598
+
1599
+ it('should show deprecation warning when using individual args for upsert', async () => {
1600
+ await vectorDB.upsert(indexName, [[1, 2, 3]], [{ test: 'data' }]);
1601
+
1602
+ expect(warnSpy).toHaveBeenCalledWith(
1603
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to upsert() is deprecated'),
1604
+ );
1605
+ });
1606
+
1607
+ it('should show deprecation warning when using individual args for query', async () => {
1608
+ await vectorDB.query(indexName, [1, 2, 3], 5);
1609
+
1610
+ expect(warnSpy).toHaveBeenCalledWith(
1611
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to query() is deprecated'),
1612
+ );
1613
+ });
1614
+
1615
+ it('should show deprecation warning when using individual args for buildIndex', async () => {
1616
+ await vectorDB.buildIndex(indexName, 'cosine', { type: 'flat' });
1617
+
1618
+ expect(warnSpy).toHaveBeenCalledWith(
1619
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to buildIndex() is deprecated'),
1620
+ );
1621
+ });
1622
+
1623
+ it('should not show deprecation warning when using object param for buildIndex', async () => {
1624
+ await vectorDB.buildIndex({
1625
+ indexName: indexName,
1626
+ metric: 'cosine',
1627
+ indexConfig: { type: 'flat' },
1628
+ });
1629
+
1630
+ expect(warnSpy).not.toHaveBeenCalled();
1631
+ });
1632
+
1633
+ it('should not show deprecation warning when using object param for query', async () => {
1634
+ await vectorDB.query({
1635
+ indexName,
1636
+ queryVector: [1, 2, 3],
1637
+ topK: 5,
1638
+ });
1639
+
1640
+ expect(warnSpy).not.toHaveBeenCalled();
1641
+ });
1642
+
1643
+ it('should not show deprecation warning when using object param for createIndex', async () => {
1644
+ await vectorDB.createIndex({
1645
+ indexName: indexName2,
1646
+ dimension: 3,
1647
+ metric: 'cosine',
1648
+ });
1649
+
1650
+ expect(warnSpy).not.toHaveBeenCalled();
1651
+ });
1652
+
1653
+ it('should not show deprecation warning when using object param for upsert', async () => {
1654
+ await vectorDB.upsert({
1655
+ indexName,
1656
+ vectors: [[1, 2, 3]],
1657
+ metadata: [{ test: 'data' }],
1658
+ });
1659
+
1660
+ expect(warnSpy).not.toHaveBeenCalled();
1661
+ });
1662
+
1663
+ it('should maintain backward compatibility with individual args', async () => {
1664
+ // Query
1665
+ const queryResults = await vectorDB.query(indexName, [1, 2, 3], 5);
1666
+ expect(Array.isArray(queryResults)).toBe(true);
1667
+
1668
+ // CreateIndex
1669
+ await expect(vectorDB.createIndex(indexName2, 3, 'cosine')).resolves.not.toThrow();
1670
+
1671
+ // Upsert
1672
+ const upsertResults = await vectorDB.upsert({
1673
+ indexName,
1674
+ vectors: [[1, 2, 3]],
1675
+ metadata: [{ test: 'data' }],
1676
+ });
1677
+ expect(Array.isArray(upsertResults)).toBe(true);
1678
+ expect(upsertResults).toHaveLength(1);
1679
+
1680
+ // BuildIndex
1681
+ await expect(vectorDB.buildIndex(indexName, 'cosine', { type: 'flat' })).resolves.not.toThrow();
1682
+ });
1683
+ });
1302
1684
  });