You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add RECOMMEND statement for point recommendations
- Introduced the RECOMMEND statement to allow users to find similar points based on known examples.
- Implemented parsing, execution, and filtering logic for the RECOMMEND statement in the QQL parser and executor.
- Updated the CLI to include documentation for the new RECOMMEND statement.
- Enhanced the executor to handle positive and negative IDs, as well as optional query filters and strategies.
- Added tests for the RECOMMEND statement to ensure correct functionality and error handling.
- Updated the sample QQL script to demonstrate the usage of the RECOMMEND statement.
@@ -186,6 +187,8 @@ Inserts a new document into a collection. The `text` field is **mandatory** —
186
187
187
188
If the collection does not exist yet, it is **created automatically** with the correct vector dimensions.
188
189
190
+
If you include an `id` field in `VALUES`, QQL uses it as the Qdrant point ID. Supported explicit IDs are unsigned integers or UUID strings. If you omit `id`, QQL generates a UUID automatically.
191
+
189
192
**Syntax:**
190
193
```
191
194
INSERT INTO COLLECTION <collection_name> VALUES {<dict>}
1. The `text` value is embedded into a dense vector using the configured model.
233
237
2. In hybrid mode, a sparse BM25 vector is also generated.
234
-
3.A UUID is auto-generated as the point ID.
235
-
4. All fields (including `text`) are stored in the payload.
238
+
3.If `id` is provided, it is used as the point ID; otherwise a UUID is auto-generated.
239
+
4. All fields except `id` are stored in the payload.
236
240
5. The point is upserted into Qdrant.
237
241
238
242
**Rules:**
239
243
-`text` is always required. Omitting it raises an error.
240
-
-A point ID (UUID) is generated automatically — you do not provide one.
244
+
-`id`, when provided, must be an unsigned integer or UUID string.
241
245
- If the collection already exists with a different vector size (from a different model), an error is raised with a clear message.
242
246
- Hybrid inserts require a hybrid collection (created with `CREATE COLLECTION ... HYBRID` or auto-created on first `USING HYBRID` insert).
243
247
@@ -249,6 +253,8 @@ Inserts multiple documents in a single statement. Each item in the array must co
249
253
250
254
If the collection does not exist yet, it is **created automatically** on the first bulk insert.
251
255
256
+
Each record may optionally include an `id` field. This is the preferred way to keep seed data deterministic and to make follow-up operations like `RECOMMEND` or `DELETE` reproducible.
257
+
252
258
**Syntax:**
253
259
```
254
260
INSERT BULK INTO COLLECTION <collection_name> VALUES [<dict>, <dict>, ...]
- Every dict in the array must contain a `"text"` key. Missing `text` on any item raises an error with the offending index.
290
296
- An empty array `[]` raises an error.
291
-
-A UUID is auto-generated for each point — you do not provide IDs.
297
+
-`id`, when provided, must be an unsigned integer or UUID string.
292
298
- Supports all the same `USING` clauses as single `INSERT`.
293
299
294
300
---
@@ -371,13 +377,57 @@ Results are displayed as a table with three columns:
371
377
```
372
378
373
379
-**Score** — similarity score. Higher is more relevant.
374
-
-**ID** — the UUID of the matching point.
380
+
-**ID** — the point ID returned by Qdrant. This may be an integer or a UUID string.
375
381
-**Payload** — all fields stored alongside the vector.
376
382
377
383
**Important:** Use the same model for SEARCH as you used for INSERT. Mixing models produces meaningless scores because the vectors live in different spaces.
378
384
379
385
---
380
386
387
+
### RECOMMEND — retrieve by example IDs
388
+
389
+
Performs a Qdrant recommendation query using existing point IDs as positive and optional negative examples.
390
+
391
+
This is useful when you already know which stored points represent the kind of result you want. Qdrant uses those examples to retrieve nearby points, and QQL automatically excludes the seed IDs from the results.
Use Qdrant's `best_score` recommendation strategy:
414
+
```sql
415
+
RECOMMEND FROM articles POSITIVE IDS (1001) STRATEGY 'best_score'LIMIT10
416
+
```
417
+
418
+
Recommend only within a filtered subset:
419
+
```sql
420
+
RECOMMEND FROM articles POSITIVE IDS (1001) LIMIT5WHERE year >=2020AND status ='published'
421
+
```
422
+
423
+
**Supported strategies:**
424
+
425
+
-`average_vector`
426
+
-`best_score`
427
+
-`sum_scores`
428
+
429
+
---
430
+
381
431
### Query-Time Search Params (`EXACT`, `WITH`)
382
432
383
433
QQL supports a small set of Qdrant query-time search parameters on `SEARCH` statements.
@@ -818,7 +868,7 @@ Raises an error if the collection does not exist.
818
868
819
869
### DELETE — remove a point
820
870
821
-
Deletes a single point from a collection by its ID. The point ID is the UUID returned by INSERT.
871
+
Deletes a single point from a collection by its ID. The ID may be an integer or a UUID string, either generated by QQL or supplied explicitly on INSERT.
822
872
823
873
**Syntax:**
824
874
```
@@ -890,9 +940,14 @@ SHOW COLLECTIONS
890
940
**Rules:**
891
941
-`--` to end-of-line is a comment and is ignored (inline or full-line)
0 commit comments