@mastra/qdrant 0.1.9-alpha.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/qdrant@0.1.9-alpha.0 build /home/runner/work/mastra/mastra/stores/qdrant
2
+ > @mastra/qdrant@0.2.0-alpha.1 build /home/runner/work/mastra/mastra/stores/qdrant
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.4.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 8010ms
9
+ TSC ⚡️ Build success in 7393ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.7.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/qdrant/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.7.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/qdrant/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 7750ms
16
+ DTS ⚡️ Build success in 7651ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- CJS dist/index.cjs 10.62 KB
21
- CJS ⚡️ Build success in 692ms
22
- ESM dist/index.js 10.58 KB
23
- ESM ⚡️ Build success in 692ms
20
+ CJS dist/index.cjs 13.17 KB
21
+ CJS ⚡️ Build success in 556ms
22
+ ESM dist/index.js 13.14 KB
23
+ ESM ⚡️ Build success in 564ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @mastra/qdrant
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6cbf6bb: Added new operation implementations for MastraVector in qdrant store
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [16b98d9]
12
+ - Updated dependencies [1c8cda4]
13
+ - Updated dependencies [95b4144]
14
+ - Updated dependencies [3729dbd]
15
+ - Updated dependencies [c2144f4]
16
+ - @mastra/core@0.6.0
17
+
18
+ ## 0.2.0-alpha.1
19
+
20
+ ### Minor Changes
21
+
22
+ - 6cbf6bb: Added new operation implementations for MastraVector in qdrant store
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies [16b98d9]
27
+ - Updated dependencies [1c8cda4]
28
+ - Updated dependencies [95b4144]
29
+ - Updated dependencies [c2144f4]
30
+ - @mastra/core@0.6.0-alpha.1
31
+
3
32
  ## 0.1.9-alpha.0
4
33
 
5
34
  ### Patch Changes
@@ -55,6 +55,41 @@ declare class QdrantVector extends MastraVector {
55
55
  listIndexes(): Promise<string[]>;
56
56
  describeIndex(indexName: string): Promise<IndexStats>;
57
57
  deleteIndex(indexName: string): Promise<void>;
58
+ updateIndexById(indexName: string, id: string, update: {
59
+ vector?: number[];
60
+ metadata?: Record<string, any>;
61
+ }): Promise<void>;
62
+ deleteIndexById(indexName: string, id: string): Promise<void>;
63
+ /**
64
+ * Parses and converts a string ID to the appropriate type (string or number) for Qdrant point operations.
65
+ *
66
+ * Qdrant supports both numeric and string IDs. This helper method ensures IDs are in the correct format
67
+ * before sending them to the Qdrant client API.
68
+ *
69
+ * @param id - The ID string to parse
70
+ * @returns The parsed ID as either a number (if string contains only digits) or the original string
71
+ *
72
+ * @example
73
+ * // Numeric ID strings are converted to numbers
74
+ * parsePointId("123") => 123
75
+ * parsePointId("42") => 42
76
+ * parsePointId("0") => 0
77
+ *
78
+ * // String IDs containing any non-digit characters remain as strings
79
+ * parsePointId("doc-123") => "doc-123"
80
+ * parsePointId("user_42") => "user_42"
81
+ * parsePointId("abc123") => "abc123"
82
+ * parsePointId("123abc") => "123abc"
83
+ * parsePointId("") => ""
84
+ * parsePointId("uuid-5678-xyz") => "uuid-5678-xyz"
85
+ *
86
+ * @remarks
87
+ * - This conversion is important because Qdrant treats numeric and string IDs differently
88
+ * - Only positive integers are converted to numbers (negative numbers with minus signs remain strings)
89
+ * - The method uses base-10 parsing, so leading zeros will be dropped in numeric conversions
90
+ * - reference: https://qdrant.tech/documentation/concepts/points/?q=qdrant+point+id#point-ids
91
+ */
92
+ private parsePointId;
58
93
  }
59
94
  export { QdrantVector }
60
95
  export { QdrantVector as QdrantVector_alias_1 }
@@ -55,6 +55,41 @@ declare class QdrantVector extends MastraVector {
55
55
  listIndexes(): Promise<string[]>;
56
56
  describeIndex(indexName: string): Promise<IndexStats>;
57
57
  deleteIndex(indexName: string): Promise<void>;
58
+ updateIndexById(indexName: string, id: string, update: {
59
+ vector?: number[];
60
+ metadata?: Record<string, any>;
61
+ }): Promise<void>;
62
+ deleteIndexById(indexName: string, id: string): Promise<void>;
63
+ /**
64
+ * Parses and converts a string ID to the appropriate type (string or number) for Qdrant point operations.
65
+ *
66
+ * Qdrant supports both numeric and string IDs. This helper method ensures IDs are in the correct format
67
+ * before sending them to the Qdrant client API.
68
+ *
69
+ * @param id - The ID string to parse
70
+ * @returns The parsed ID as either a number (if string contains only digits) or the original string
71
+ *
72
+ * @example
73
+ * // Numeric ID strings are converted to numbers
74
+ * parsePointId("123") => 123
75
+ * parsePointId("42") => 42
76
+ * parsePointId("0") => 0
77
+ *
78
+ * // String IDs containing any non-digit characters remain as strings
79
+ * parsePointId("doc-123") => "doc-123"
80
+ * parsePointId("user_42") => "user_42"
81
+ * parsePointId("abc123") => "abc123"
82
+ * parsePointId("123abc") => "123abc"
83
+ * parsePointId("") => ""
84
+ * parsePointId("uuid-5678-xyz") => "uuid-5678-xyz"
85
+ *
86
+ * @remarks
87
+ * - This conversion is important because Qdrant treats numeric and string IDs differently
88
+ * - Only positive integers are converted to numbers (negative numbers with minus signs remain strings)
89
+ * - The method uses base-10 parsing, so leading zeros will be dropped in numeric conversions
90
+ * - reference: https://qdrant.tech/documentation/concepts/points/?q=qdrant+point+id#point-ids
91
+ */
92
+ private parsePointId;
58
93
  }
59
94
  export { QdrantVector }
60
95
  export { QdrantVector as QdrantVector_alias_1 }
package/dist/index.cjs CHANGED
@@ -337,6 +337,84 @@ var QdrantVector = class extends vector.MastraVector {
337
337
  async deleteIndex(indexName) {
338
338
  await this.client.deleteCollection(indexName);
339
339
  }
340
+ async updateIndexById(indexName, id, update) {
341
+ if (!update.vector && !update.metadata) {
342
+ throw new Error("No updates provided");
343
+ }
344
+ const pointId = this.parsePointId(id);
345
+ try {
346
+ if (update.metadata && !update.vector) {
347
+ await this.client.setPayload(indexName, { payload: update.metadata, points: [pointId] });
348
+ return;
349
+ }
350
+ if (update.vector && !update.metadata) {
351
+ await this.client.updateVectors(indexName, {
352
+ points: [
353
+ {
354
+ id: pointId,
355
+ vector: update.vector
356
+ }
357
+ ]
358
+ });
359
+ return;
360
+ }
361
+ if (update.vector && update.metadata) {
362
+ const point = {
363
+ id: pointId,
364
+ vector: update.vector,
365
+ payload: update.metadata
366
+ };
367
+ await this.client.upsert(indexName, {
368
+ points: [point]
369
+ });
370
+ return;
371
+ }
372
+ } catch (error) {
373
+ console.error("Error updating point in Qdrant:", error);
374
+ throw error;
375
+ }
376
+ }
377
+ async deleteIndexById(indexName, id) {
378
+ const pointId = this.parsePointId(id);
379
+ await this.client.delete(indexName, {
380
+ points: [pointId]
381
+ });
382
+ }
383
+ /**
384
+ * Parses and converts a string ID to the appropriate type (string or number) for Qdrant point operations.
385
+ *
386
+ * Qdrant supports both numeric and string IDs. This helper method ensures IDs are in the correct format
387
+ * before sending them to the Qdrant client API.
388
+ *
389
+ * @param id - The ID string to parse
390
+ * @returns The parsed ID as either a number (if string contains only digits) or the original string
391
+ *
392
+ * @example
393
+ * // Numeric ID strings are converted to numbers
394
+ * parsePointId("123") => 123
395
+ * parsePointId("42") => 42
396
+ * parsePointId("0") => 0
397
+ *
398
+ * // String IDs containing any non-digit characters remain as strings
399
+ * parsePointId("doc-123") => "doc-123"
400
+ * parsePointId("user_42") => "user_42"
401
+ * parsePointId("abc123") => "abc123"
402
+ * parsePointId("123abc") => "123abc"
403
+ * parsePointId("") => ""
404
+ * parsePointId("uuid-5678-xyz") => "uuid-5678-xyz"
405
+ *
406
+ * @remarks
407
+ * - This conversion is important because Qdrant treats numeric and string IDs differently
408
+ * - Only positive integers are converted to numbers (negative numbers with minus signs remain strings)
409
+ * - The method uses base-10 parsing, so leading zeros will be dropped in numeric conversions
410
+ * - reference: https://qdrant.tech/documentation/concepts/points/?q=qdrant+point+id#point-ids
411
+ */
412
+ parsePointId(id) {
413
+ if (/^\d+$/.test(id)) {
414
+ return parseInt(id, 10);
415
+ }
416
+ return id;
417
+ }
340
418
  };
341
419
 
342
420
  exports.QdrantVector = QdrantVector;
package/dist/index.js CHANGED
@@ -335,6 +335,84 @@ var QdrantVector = class extends MastraVector {
335
335
  async deleteIndex(indexName) {
336
336
  await this.client.deleteCollection(indexName);
337
337
  }
338
+ async updateIndexById(indexName, id, update) {
339
+ if (!update.vector && !update.metadata) {
340
+ throw new Error("No updates provided");
341
+ }
342
+ const pointId = this.parsePointId(id);
343
+ try {
344
+ if (update.metadata && !update.vector) {
345
+ await this.client.setPayload(indexName, { payload: update.metadata, points: [pointId] });
346
+ return;
347
+ }
348
+ if (update.vector && !update.metadata) {
349
+ await this.client.updateVectors(indexName, {
350
+ points: [
351
+ {
352
+ id: pointId,
353
+ vector: update.vector
354
+ }
355
+ ]
356
+ });
357
+ return;
358
+ }
359
+ if (update.vector && update.metadata) {
360
+ const point = {
361
+ id: pointId,
362
+ vector: update.vector,
363
+ payload: update.metadata
364
+ };
365
+ await this.client.upsert(indexName, {
366
+ points: [point]
367
+ });
368
+ return;
369
+ }
370
+ } catch (error) {
371
+ console.error("Error updating point in Qdrant:", error);
372
+ throw error;
373
+ }
374
+ }
375
+ async deleteIndexById(indexName, id) {
376
+ const pointId = this.parsePointId(id);
377
+ await this.client.delete(indexName, {
378
+ points: [pointId]
379
+ });
380
+ }
381
+ /**
382
+ * Parses and converts a string ID to the appropriate type (string or number) for Qdrant point operations.
383
+ *
384
+ * Qdrant supports both numeric and string IDs. This helper method ensures IDs are in the correct format
385
+ * before sending them to the Qdrant client API.
386
+ *
387
+ * @param id - The ID string to parse
388
+ * @returns The parsed ID as either a number (if string contains only digits) or the original string
389
+ *
390
+ * @example
391
+ * // Numeric ID strings are converted to numbers
392
+ * parsePointId("123") => 123
393
+ * parsePointId("42") => 42
394
+ * parsePointId("0") => 0
395
+ *
396
+ * // String IDs containing any non-digit characters remain as strings
397
+ * parsePointId("doc-123") => "doc-123"
398
+ * parsePointId("user_42") => "user_42"
399
+ * parsePointId("abc123") => "abc123"
400
+ * parsePointId("123abc") => "123abc"
401
+ * parsePointId("") => ""
402
+ * parsePointId("uuid-5678-xyz") => "uuid-5678-xyz"
403
+ *
404
+ * @remarks
405
+ * - This conversion is important because Qdrant treats numeric and string IDs differently
406
+ * - Only positive integers are converted to numbers (negative numbers with minus signs remain strings)
407
+ * - The method uses base-10 parsing, so leading zeros will be dropped in numeric conversions
408
+ * - reference: https://qdrant.tech/documentation/concepts/points/?q=qdrant+point+id#point-ids
409
+ */
410
+ parsePointId(id) {
411
+ if (/^\d+$/.test(id)) {
412
+ return parseInt(id, 10);
413
+ }
414
+ return id;
415
+ }
338
416
  };
339
417
 
340
418
  export { QdrantVector };
@@ -0,0 +1,17 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ qdrant:
5
+ image: qdrant/qdrant:latest
6
+ ports:
7
+ - '6333:6333' # REST API port
8
+ - '6334:6334' # gRPC port
9
+ volumes:
10
+ - qdrant_data:/qdrant/storage
11
+ environment:
12
+ - QDRANT_LOG_LEVEL=INFO
13
+ restart: always
14
+
15
+ volumes:
16
+ qdrant_data:
17
+ driver: local
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/qdrant",
3
- "version": "0.1.9-alpha.0",
3
+ "version": "0.2.0",
4
4
  "description": "Qdrant vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@qdrant/js-client-rest": "^1.13.0",
23
- "@mastra/core": "^0.5.1-alpha.0"
23
+ "@mastra/core": "^0.6.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@microsoft/api-extractor": "^7.52.1",
@@ -3,6 +3,7 @@
3
3
  import { describe, it, expect, beforeAll, afterAll, afterEach, vi, beforeEach } from 'vitest';
4
4
 
5
5
  import { QdrantVector } from './index';
6
+ import type { QueryResult } from '@mastra/core';
6
7
 
7
8
  const dimension = 3;
8
9
 
@@ -87,6 +88,157 @@ describe('QdrantVector', () => {
87
88
  }, 50000);
88
89
  });
89
90
 
91
+ describe('Vector update operations', () => {
92
+ const testVectors = [
93
+ [1, 2, 3],
94
+ [4, 5, 6],
95
+ [7, 8, 9],
96
+ ];
97
+
98
+ beforeEach(async () => {
99
+ await qdrant.createIndex({ indexName: testCollectionName, dimension: 3 });
100
+ });
101
+
102
+ afterEach(async () => {
103
+ await qdrant.deleteIndex(testCollectionName);
104
+ });
105
+
106
+ it('should update the vector by id', async () => {
107
+ const ids = await qdrant.upsert({ indexName: testCollectionName, vectors: testVectors });
108
+ expect(ids).toHaveLength(3);
109
+
110
+ const idToBeUpdated = ids[0];
111
+ const newVector = [1, 2, 3];
112
+ const newMetaData = {
113
+ test: 'updates',
114
+ };
115
+
116
+ const update = {
117
+ vector: newVector,
118
+ metadata: newMetaData,
119
+ };
120
+
121
+ await qdrant.updateIndexById(testCollectionName, idToBeUpdated, update);
122
+
123
+ const results: QueryResult[] = await qdrant.query({
124
+ indexName: testCollectionName,
125
+ queryVector: newVector,
126
+ topK: 2,
127
+ includeVector: true,
128
+ });
129
+ console.log(results);
130
+ expect(results[0]?.id).toBe(idToBeUpdated);
131
+ // not matching the vector in results list because, the stored vector is stored in a normalized form inside qdrant
132
+ // expect(results[0]?.vector).toEqual(newVector);
133
+ expect(results[0]?.metadata).toEqual(newMetaData);
134
+ });
135
+
136
+ it('should only update the metadata by id', async () => {
137
+ const ids = await qdrant.upsert({ indexName: testCollectionName, vectors: testVectors });
138
+ expect(ids).toHaveLength(3);
139
+
140
+ const idToBeUpdated = ids[0];
141
+ const newMetaData = {
142
+ test: 'updates',
143
+ };
144
+
145
+ const update = {
146
+ metadata: newMetaData,
147
+ };
148
+
149
+ await qdrant.updateIndexById(testCollectionName, idToBeUpdated, update);
150
+
151
+ const results: QueryResult[] = await qdrant.query({
152
+ indexName: testCollectionName,
153
+ queryVector: testVectors[0],
154
+ topK: 2,
155
+ includeVector: true,
156
+ });
157
+ expect(results[0]?.id).toBe(idToBeUpdated);
158
+ // not matching the vector in results list because, the stored vector is stored in a normalized form inside qdrant
159
+ // expect(results[0]?.vector).toEqual(testVectors[0]);
160
+ expect(results[0]?.metadata).toEqual(newMetaData);
161
+ });
162
+
163
+ it('should only update vector embeddings by id', async () => {
164
+ const ids = await qdrant.upsert({ indexName: testCollectionName, vectors: testVectors });
165
+ expect(ids).toHaveLength(3);
166
+
167
+ const idToBeUpdated = ids[0];
168
+ const newVector = [1, 2, 3];
169
+
170
+ const update = {
171
+ vector: newVector,
172
+ };
173
+
174
+ await qdrant.updateIndexById(testCollectionName, idToBeUpdated, update);
175
+
176
+ const results: QueryResult[] = await qdrant.query({
177
+ indexName: testCollectionName,
178
+ queryVector: newVector,
179
+ topK: 2,
180
+ includeVector: true,
181
+ });
182
+ expect(results[0]?.id).toBe(idToBeUpdated);
183
+ // not matching the vector in results list because, the stored vector is stored in a normalized form inside qdrant
184
+ // expect(results[0]?.vector).toEqual(newVector);
185
+ });
186
+
187
+ it('should throw exception when no updates are given', () => {
188
+ expect(qdrant.updateIndexById(testCollectionName, 'id', {})).rejects.toThrow('No updates provided');
189
+ });
190
+
191
+ it('should throw error for non-existent index', async () => {
192
+ const nonExistentIndex = 'non-existent-index';
193
+ await expect(qdrant.updateIndexById(nonExistentIndex, 'test-id', { vector: [1, 2, 3] })).rejects.toThrow();
194
+ });
195
+
196
+ it('should throw error for invalid vector dimension', async () => {
197
+ const [id] = await qdrant.upsert({
198
+ indexName: testCollectionName,
199
+ vectors: [[1, 2, 3]],
200
+ metadata: [{ test: 'initial' }],
201
+ });
202
+
203
+ await expect(
204
+ qdrant.updateIndexById(testCollectionName, id, { vector: [1, 2] }), // Wrong dimension
205
+ ).rejects.toThrow();
206
+ });
207
+ });
208
+
209
+ describe('Vector delete operations', () => {
210
+ const testVectors = [
211
+ [1, 2, 3],
212
+ [4, 5, 6],
213
+ [7, 8, 9],
214
+ ];
215
+
216
+ beforeEach(async () => {
217
+ await qdrant.createIndex({ indexName: testCollectionName, dimension: 3 });
218
+ });
219
+
220
+ afterEach(async () => {
221
+ await qdrant.deleteIndex(testCollectionName);
222
+ });
223
+
224
+ it('should delete the vector by id', async () => {
225
+ const ids = await qdrant.upsert({ indexName: testCollectionName, vectors: testVectors });
226
+ expect(ids).toHaveLength(3);
227
+ const idToBeDeleted = ids[0];
228
+
229
+ await qdrant.deleteIndexById(testCollectionName, idToBeDeleted);
230
+
231
+ const results: QueryResult[] = await qdrant.query({
232
+ indexName: testCollectionName,
233
+ queryVector: [1.0, 0.0, 0.0],
234
+ topK: 2,
235
+ });
236
+
237
+ expect(results).toHaveLength(2);
238
+ expect(results.map(res => res.id)).not.toContain(idToBeDeleted);
239
+ });
240
+ });
241
+
90
242
  describe('Filter Queries', () => {
91
243
  const filterTestVectors = Array(10)
92
244
  .fill(null)
@@ -148,4 +148,105 @@ export class QdrantVector extends MastraVector {
148
148
  async deleteIndex(indexName: string): Promise<void> {
149
149
  await this.client.deleteCollection(indexName);
150
150
  }
151
+
152
+ async updateIndexById(
153
+ indexName: string,
154
+ id: string,
155
+ update: {
156
+ vector?: number[];
157
+ metadata?: Record<string, any>;
158
+ },
159
+ ): Promise<void> {
160
+ if (!update.vector && !update.metadata) {
161
+ throw new Error('No updates provided');
162
+ }
163
+
164
+ const pointId = this.parsePointId(id);
165
+
166
+ try {
167
+ // Handle metadata-only update
168
+ if (update.metadata && !update.vector) {
169
+ // For metadata-only updates, use the setPayload method
170
+ await this.client.setPayload(indexName, { payload: update.metadata, points: [pointId] });
171
+ return;
172
+ }
173
+
174
+ // Handle vector-only update
175
+ if (update.vector && !update.metadata) {
176
+ await this.client.updateVectors(indexName, {
177
+ points: [
178
+ {
179
+ id: pointId,
180
+ vector: update.vector,
181
+ },
182
+ ],
183
+ });
184
+ return;
185
+ }
186
+
187
+ // Handle both vector and metadata update
188
+ if (update.vector && update.metadata) {
189
+ const point = {
190
+ id: pointId,
191
+ vector: update.vector,
192
+ payload: update.metadata,
193
+ };
194
+
195
+ await this.client.upsert(indexName, {
196
+ points: [point],
197
+ });
198
+ return;
199
+ }
200
+ } catch (error) {
201
+ console.error('Error updating point in Qdrant:', error);
202
+ throw error;
203
+ }
204
+ }
205
+
206
+ async deleteIndexById(indexName: string, id: string): Promise<void> {
207
+ // Parse the ID - Qdrant supports both string and numeric IDs
208
+ const pointId = this.parsePointId(id);
209
+
210
+ // Use the Qdrant client to delete the point from the collection
211
+ await this.client.delete(indexName, {
212
+ points: [pointId],
213
+ });
214
+ }
215
+
216
+ /**
217
+ * Parses and converts a string ID to the appropriate type (string or number) for Qdrant point operations.
218
+ *
219
+ * Qdrant supports both numeric and string IDs. This helper method ensures IDs are in the correct format
220
+ * before sending them to the Qdrant client API.
221
+ *
222
+ * @param id - The ID string to parse
223
+ * @returns The parsed ID as either a number (if string contains only digits) or the original string
224
+ *
225
+ * @example
226
+ * // Numeric ID strings are converted to numbers
227
+ * parsePointId("123") => 123
228
+ * parsePointId("42") => 42
229
+ * parsePointId("0") => 0
230
+ *
231
+ * // String IDs containing any non-digit characters remain as strings
232
+ * parsePointId("doc-123") => "doc-123"
233
+ * parsePointId("user_42") => "user_42"
234
+ * parsePointId("abc123") => "abc123"
235
+ * parsePointId("123abc") => "123abc"
236
+ * parsePointId("") => ""
237
+ * parsePointId("uuid-5678-xyz") => "uuid-5678-xyz"
238
+ *
239
+ * @remarks
240
+ * - This conversion is important because Qdrant treats numeric and string IDs differently
241
+ * - Only positive integers are converted to numbers (negative numbers with minus signs remain strings)
242
+ * - The method uses base-10 parsing, so leading zeros will be dropped in numeric conversions
243
+ * - reference: https://qdrant.tech/documentation/concepts/points/?q=qdrant+point+id#point-ids
244
+ */
245
+ private parsePointId(id: string): string | number {
246
+ // Try to parse as number if it looks like one
247
+ if (/^\d+$/.test(id)) {
248
+ return parseInt(id, 10);
249
+ }
250
+ return id;
251
+ }
151
252
  }