@mastra/qdrant 1.0.0 → 1.0.1-alpha.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.
@@ -0,0 +1,222 @@
1
+ # Qdrant Vector Store
2
+
3
+ The QdrantVector class provides vector search using [Qdrant](https://qdrant.tech/), a vector similarity search engine. It provides a production-ready service with a convenient API to store, search, and manage vectors with additional payload and extended filtering support.
4
+
5
+ ## Constructor Options
6
+
7
+ **url:** (`string`): REST URL of the Qdrant instance. Eg. https\://xyz-example.eu-central.aws.cloud.qdrant.io:6333
8
+
9
+ **apiKey:** (`string`): Optional Qdrant API key
10
+
11
+ **https:** (`boolean`): Whether to use TLS when setting up the connection. Recommended.
12
+
13
+ ## Methods
14
+
15
+ ### createIndex()
16
+
17
+ **indexName:** (`string`): Name of the index to create
18
+
19
+ **dimension:** (`number`): Vector dimension (must match your embedding model). Required for single-vector collections.
20
+
21
+ **metric?:** (`'cosine' | 'euclidean' | 'dotproduct'`): Distance metric for similarity search (Default: `cosine`)
22
+
23
+ **namedVectors?:** (`Record<string, { size: number; distance: 'cosine' | 'euclidean' | 'dotproduct' }>`): Configuration for named vector spaces. When provided, creates a collection with multiple named vector fields.
24
+
25
+ #### Creating a Named Vectors Collection
26
+
27
+ ```typescript
28
+ // Create a collection with multiple named vector spaces
29
+ await store.createIndex({
30
+ indexName: 'multi_modal',
31
+ dimension: 768, // fallback
32
+ namedVectors: {
33
+ text: { size: 768, distance: 'cosine' },
34
+ image: { size: 512, distance: 'euclidean' },
35
+ },
36
+ })
37
+ ```
38
+
39
+ ### upsert()
40
+
41
+ **indexName:** (`string`): Name of the index to upsert into
42
+
43
+ **vectors:** (`number[][]`): Array of embedding vectors
44
+
45
+ **metadata?:** (`Record<string, any>[]`): Metadata for each vector
46
+
47
+ **ids?:** (`string[]`): Optional vector IDs (auto-generated if not provided)
48
+
49
+ **vectorName?:** (`string`): Name of the vector space to upsert into when using named vectors.
50
+
51
+ #### Upserting into Named Vector Spaces
52
+
53
+ ```typescript
54
+ // Upsert into the "text" vector space
55
+ await store.upsert({
56
+ indexName: 'multi_modal',
57
+ vectors: textEmbeddings,
58
+ metadata: textMetadata,
59
+ vectorName: 'text',
60
+ })
61
+
62
+ // Upsert into the "image" vector space
63
+ await store.upsert({
64
+ indexName: 'multi_modal',
65
+ vectors: imageEmbeddings,
66
+ metadata: imageMetadata,
67
+ vectorName: 'image',
68
+ })
69
+ ```
70
+
71
+ ### query()
72
+
73
+ **indexName:** (`string`): Name of the index to query
74
+
75
+ **queryVector:** (`number[]`): Query vector to find similar vectors
76
+
77
+ **topK?:** (`number`): Number of results to return (Default: `10`)
78
+
79
+ **filter?:** (`Record<string, any>`): Metadata filters for the query
80
+
81
+ **includeVector?:** (`boolean`): Whether to include vectors in the results (Default: `false`)
82
+
83
+ **using?:** (`string`): Name of the vector field to query when using named vectors. Use this when your collection has multiple named vector fields.
84
+
85
+ #### Named Vectors
86
+
87
+ Qdrant supports [named vectors](https://qdrant.tech/documentation/concepts/vectors/#named-vectors), allowing multiple vector fields per collection. Use the `using` parameter to specify which named vector to query against:
88
+
89
+ ```typescript
90
+ const results = await store.query({
91
+ indexName: 'my_index',
92
+ queryVector: embedding,
93
+ topK: 10,
94
+ using: 'title_embedding', // Query against a specific named vector
95
+ })
96
+ ```
97
+
98
+ ### listIndexes()
99
+
100
+ Returns an array of index names as strings.
101
+
102
+ ### describeIndex()
103
+
104
+ **indexName:** (`string`): Name of the index to describe
105
+
106
+ Returns:
107
+
108
+ ```typescript
109
+ interface IndexStats {
110
+ dimension: number
111
+ count: number
112
+ metric: 'cosine' | 'euclidean' | 'dotproduct'
113
+ }
114
+ ```
115
+
116
+ ### deleteIndex()
117
+
118
+ **indexName:** (`string`): Name of the index to delete
119
+
120
+ ### updateVector()
121
+
122
+ Update a single vector by ID or by metadata filter. Either `id` or `filter` must be provided, but not both.
123
+
124
+ **indexName:** (`string`): Name of the index to update
125
+
126
+ **id?:** (`string`): ID of the vector to update (mutually exclusive with filter)
127
+
128
+ **filter?:** (`Record<string, any>`): Metadata filter to identify vector(s) to update (mutually exclusive with id)
129
+
130
+ **update:** (`{ vector?: number[]; metadata?: Record<string, any>; }`): Object containing the vector and/or metadata to update
131
+
132
+ Updates a vector and/or its metadata in the specified index. If both vector and metadata are provided, both will be updated. If only one is provided, only that will be updated.
133
+
134
+ ### deleteVector()
135
+
136
+ **indexName:** (`string`): Name of the index from which to delete the vector
137
+
138
+ **id:** (`string`): ID of the vector to delete
139
+
140
+ Deletes a vector from the specified index by its ID.
141
+
142
+ ### deleteVectors()
143
+
144
+ Delete multiple vectors by IDs or by metadata filter. Either `ids` or `filter` must be provided, but not both.
145
+
146
+ **indexName:** (`string`): Name of the index containing the vectors to delete
147
+
148
+ **ids?:** (`string[]`): Array of vector IDs to delete (mutually exclusive with filter)
149
+
150
+ **filter?:** (`Record<string, any>`): Metadata filter to identify vectors to delete (mutually exclusive with ids)
151
+
152
+ ### createPayloadIndex()
153
+
154
+ Creates a payload (metadata) index on a collection field to enable efficient filtering. This is **required** for Qdrant Cloud and any Qdrant instance with `strict_mode_config = true`.
155
+
156
+ **indexName:** (`string`): Name of the collection to create the payload index on
157
+
158
+ **fieldName:** (`string`): Name of the payload field to index
159
+
160
+ **fieldSchema:** (`'keyword' | 'integer' | 'float' | 'geo' | 'text' | 'bool' | 'datetime' | 'uuid'`): The schema type for the payload field
161
+
162
+ **wait?:** (`boolean`): Whether to wait for the operation to complete (Default: `true`)
163
+
164
+ ```typescript
165
+ // Create a keyword index for filtering by source
166
+ await store.createPayloadIndex({
167
+ indexName: 'my_index',
168
+ fieldName: 'source',
169
+ fieldSchema: 'keyword',
170
+ })
171
+
172
+ const results = await store.query({
173
+ indexName: 'my_index',
174
+ queryVector: queryVector,
175
+ filter: { source: 'document-a' },
176
+ })
177
+ ```
178
+
179
+ ### deletePayloadIndex()
180
+
181
+ Removes a payload index from a collection field.
182
+
183
+ **indexName:** (`string`): Name of the collection to delete the payload index from
184
+
185
+ **fieldName:** (`string`): Name of the payload field index to delete
186
+
187
+ **wait?:** (`boolean`): Whether to wait for the operation to complete (Default: `true`)
188
+
189
+ ## Response Types
190
+
191
+ Query results are returned in this format:
192
+
193
+ ```typescript
194
+ interface QueryResult {
195
+ id: string
196
+ score: number
197
+ metadata: Record<string, any>
198
+ vector?: number[] // Only included if includeVector is true
199
+ }
200
+ ```
201
+
202
+ ## Error Handling
203
+
204
+ The store throws typed errors that can be caught:
205
+
206
+ ```typescript
207
+ try {
208
+ await store.query({
209
+ indexName: 'index_name',
210
+ queryVector: queryVector,
211
+ })
212
+ } catch (error) {
213
+ if (error instanceof VectorStoreError) {
214
+ console.log(error.code) // 'connection_failed' | 'invalid_dimension' | etc
215
+ console.log(error.details) // Additional error context
216
+ }
217
+ }
218
+ ```
219
+
220
+ ## Related
221
+
222
+ - [Metadata Filters](https://mastra.ai/reference/rag/metadata-filters)
package/dist/index.cjs CHANGED
@@ -491,6 +491,15 @@ var QdrantVector = class extends vector.MastraVector {
491
491
  includeVector = false,
492
492
  using
493
493
  }) {
494
+ if (!queryVector) {
495
+ throw new error.MastraError({
496
+ id: storage.createVectorErrorId("QDRANT", "QUERY", "MISSING_VECTOR"),
497
+ text: "queryVector is required for Qdrant queries. Metadata-only queries are not supported by this vector store.",
498
+ domain: error.ErrorDomain.STORAGE,
499
+ category: error.ErrorCategory.USER,
500
+ details: { indexName }
501
+ });
502
+ }
494
503
  const translatedFilter = this.transformFilter(filter) ?? {};
495
504
  try {
496
505
  const results = (await this.client.query(indexName, {
@@ -561,7 +570,7 @@ var QdrantVector = class extends vector.MastraVector {
561
570
  return {
562
571
  dimension: config.params.vectors?.size,
563
572
  count: points_count || 0,
564
- // @ts-expect-error
573
+ // @ts-expect-error - Object.keys returns string[] but DISTANCE_MAPPING keys are typed
565
574
  metric: Object.keys(DISTANCE_MAPPING).find((key) => DISTANCE_MAPPING[key] === distance)
566
575
  };
567
576
  } catch (error$1) {