qql-cli 2.0.0__tar.gz → 2.2.0__tar.gz
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.
- {qql_cli-2.0.0 → qql_cli-2.2.0}/PKG-INFO +21 -9
- {qql_cli-2.0.0 → qql_cli-2.2.0}/README.md +18 -6
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/collections.md +52 -14
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/getting-started.md +8 -2
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/index.html +3 -3
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/programmatic.md +18 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/reference.md +8 -3
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/scripts.md +3 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/search.md +57 -5
- {qql_cli-2.0.0 → qql_cli-2.2.0}/pyproject.toml +3 -3
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/ast_nodes.py +21 -2
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/cli.py +43 -3
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/dumper.py +11 -6
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/executor.py +105 -5
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/lexer.py +17 -1
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/parser.py +97 -14
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/script.py +3 -1
- {qql_cli-2.0.0 → qql_cli-2.2.0}/tests/test_dumper.py +39 -5
- {qql_cli-2.0.0 → qql_cli-2.2.0}/tests/test_executor.py +227 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/tests/test_lexer.py +22 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/tests/test_parser.py +150 -1
- {qql_cli-2.0.0 → qql_cli-2.2.0}/tests/test_script.py +24 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/.github/workflows/ci.yml +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/.github/workflows/publish.yml +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/.gitignore +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/LICENSE +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/_config.yml +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/filters.md +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/insert.md +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/robots.txt +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/docs/sitemap.xml +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/main.py +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/resources/Features.md +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/resources/sample.qql +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/resources/sample_v2.qql +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/__init__.py +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/config.py +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/embedder.py +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/src/qql/exceptions.py +0 -0
- {qql_cli-2.0.0 → qql_cli-2.2.0}/tests/__init__.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qql-cli
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary: QQL is a SQL-like query language and CLI for Qdrant vector database. Write INSERT, SEARCH, RECOMMEND, DELETE, and CREATE COLLECTION statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, binary, product), WHERE clause filters, script execution, and collection dump/restore.
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: QQL is a SQL-like query language and CLI for Qdrant vector database. Write INSERT, SEARCH, RECOMMEND, DELETE, and CREATE COLLECTION statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, turbo, binary, product), WHERE clause filters, script execution, and collection dump/restore.
|
|
5
5
|
Project-URL: Homepage, https://github.com/pavanjava/qql
|
|
6
6
|
Project-URL: Repository, https://github.com/pavanjava/qql
|
|
7
7
|
Project-URL: Documentation, https://pavanjava.github.io/qql
|
|
@@ -45,7 +45,7 @@ Classifier: Topic :: Utilities
|
|
|
45
45
|
Requires-Python: >=3.12
|
|
46
46
|
Requires-Dist: click>=8.1.0
|
|
47
47
|
Requires-Dist: prompt-toolkit>=3.0.0
|
|
48
|
-
Requires-Dist: qdrant-client[fastembed]>=1.
|
|
48
|
+
Requires-Dist: qdrant-client[fastembed]>=1.18.0
|
|
49
49
|
Requires-Dist: rich>=13.0.0
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
|
|
@@ -56,9 +56,9 @@ Description-Content-Type: text/markdown
|
|
|
56
56
|
[](https://pypi.org/project/qql-cli/)
|
|
57
57
|
[](https://pypi.org/project/qql-cli/)
|
|
58
58
|
[](LICENSE)
|
|
59
|
-
[](tests/)
|
|
60
60
|
|
|
61
|
-
Write `INSERT`, `SEARCH`, `RECOMMEND`, `DELETE`, and `CREATE COLLECTION` statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, binary, product), SQL-style `WHERE` filters, script execution, and collection dump/restore.
|
|
61
|
+
Write `INSERT`, `SELECT`, `SEARCH`, `SCROLL`, `RECOMMEND`, `DELETE`, and `CREATE COLLECTION` statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, turbo, binary, product), SQL-style `WHERE` filters, script execution, and collection dump/restore.
|
|
62
62
|
|
|
63
63
|
```
|
|
64
64
|
qql> INSERT INTO COLLECTION notes VALUES {'text': 'Qdrant is a vector database', 'author': 'alice', 'year': 2024}
|
|
@@ -99,7 +99,7 @@ Your query string
|
|
|
99
99
|
Qdrant instance
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
When you run `INSERT`, the `text` field is automatically converted into a dense vector using [Fastembed](https://github.com/qdrant/fastembed). In **hybrid mode** (`USING HYBRID`), a sparse BM25 vector is also generated alongside the dense vector, and searches use Qdrant's Reciprocal Rank Fusion (RRF) to merge the results of both retrieval methods.
|
|
102
|
+
When you run `INSERT`, the `text` field is automatically converted into a dense vector using [Fastembed](https://github.com/qdrant/fastembed). In **hybrid mode** (`USING HYBRID`), a sparse BM25 vector is also generated alongside the dense vector, and searches use Qdrant's Reciprocal Rank Fusion (RRF) by default to merge the results of both retrieval methods. You can switch hybrid search to DBSF with `FUSION 'dbsf'`.
|
|
103
103
|
|
|
104
104
|
---
|
|
105
105
|
|
|
@@ -133,9 +133,9 @@ Full documentation lives in the [`docs/`](docs/) folder and at **[pavanjava.gith
|
|
|
133
133
|
|---|---|
|
|
134
134
|
| [Getting Started](docs/getting-started.md) | Installation, connecting, first queries |
|
|
135
135
|
| [INSERT / INSERT BULK](docs/insert.md) | Adding documents, batch inserts, payload types |
|
|
136
|
-
| [SEARCH / RECOMMEND / Hybrid / RERANK](docs/search.md) | Semantic search, hybrid, reranking, recommendations |
|
|
136
|
+
| [SEARCH / SELECT / SCROLL / RECOMMEND / Hybrid / RERANK](docs/search.md) | Semantic search, point retrieval, pagination, hybrid, reranking, recommendations |
|
|
137
137
|
| [WHERE Filters](docs/filters.md) | Full SQL-style filter operators |
|
|
138
|
-
| [Collections & Quantization](docs/collections.md) | CREATE, DROP, QUANTIZE (scalar/binary/product), CREATE INDEX |
|
|
138
|
+
| [Collections & Quantization](docs/collections.md) | CREATE, DROP, QUANTIZE (scalar/turbo/binary/product), CREATE INDEX |
|
|
139
139
|
| [Scripts: EXECUTE / DUMP](docs/scripts.md) | Script files, collection backup/restore |
|
|
140
140
|
| [Programmatic Usage](docs/programmatic.md) | Use QQL as a Python library |
|
|
141
141
|
| [Reference: Models / Config / Errors](docs/reference.md) | Embedding models, config file, error reference |
|
|
@@ -153,15 +153,27 @@ INSERT BULK INTO COLLECTION articles VALUES [{'text': '...'}, {'text': '...'}]
|
|
|
153
153
|
SEARCH articles SIMILAR TO 'query' LIMIT 10
|
|
154
154
|
SEARCH articles SIMILAR TO 'query' LIMIT 10 WHERE year >= 2020
|
|
155
155
|
SEARCH articles SIMILAR TO 'query' LIMIT 10 USING HYBRID
|
|
156
|
+
SEARCH articles SIMILAR TO 'query' LIMIT 10 USING HYBRID FUSION 'dbsf'
|
|
156
157
|
SEARCH articles SIMILAR TO 'query' LIMIT 10 USING HYBRID RERANK
|
|
157
158
|
|
|
159
|
+
-- Scroll
|
|
160
|
+
SCROLL FROM articles LIMIT 50
|
|
161
|
+
SCROLL FROM articles WHERE year >= 2024 LIMIT 50
|
|
162
|
+
SCROLL FROM articles AFTER 'cursor-id' LIMIT 50
|
|
163
|
+
|
|
158
164
|
-- Recommend
|
|
159
165
|
RECOMMEND FROM articles POSITIVE IDS (1001, 1002) LIMIT 5
|
|
160
166
|
|
|
167
|
+
-- Select (retrieve a point by ID)
|
|
168
|
+
SELECT * FROM articles WHERE id = '3f2e1a4b-...'
|
|
169
|
+
|
|
161
170
|
-- Collections
|
|
162
171
|
CREATE COLLECTION articles
|
|
163
172
|
CREATE COLLECTION articles HYBRID
|
|
164
173
|
CREATE COLLECTION articles QUANTIZE SCALAR
|
|
174
|
+
CREATE COLLECTION articles QUANTIZE TURBO
|
|
175
|
+
CREATE COLLECTION articles QUANTIZE TURBO BITS 2
|
|
176
|
+
CREATE COLLECTION articles QUANTIZE TURBO BITS 1.5 ALWAYS RAM
|
|
165
177
|
CREATE INDEX ON COLLECTION articles FOR year TYPE integer
|
|
166
178
|
SHOW COLLECTIONS
|
|
167
179
|
DROP COLLECTION articles
|
|
@@ -185,7 +197,7 @@ Tests do not require a running Qdrant instance — the Qdrant client is mocked.
|
|
|
185
197
|
pytest tests/ -v
|
|
186
198
|
```
|
|
187
199
|
|
|
188
|
-
Expected: **
|
|
200
|
+
Expected: **405 tests passing**.
|
|
189
201
|
|
|
190
202
|
---
|
|
191
203
|
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
[](https://pypi.org/project/qql-cli/)
|
|
6
6
|
[](https://pypi.org/project/qql-cli/)
|
|
7
7
|
[](LICENSE)
|
|
8
|
-
[](tests/)
|
|
9
9
|
|
|
10
|
-
Write `INSERT`, `SEARCH`, `RECOMMEND`, `DELETE`, and `CREATE COLLECTION` statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, binary, product), SQL-style `WHERE` filters, script execution, and collection dump/restore.
|
|
10
|
+
Write `INSERT`, `SELECT`, `SEARCH`, `SCROLL`, `RECOMMEND`, `DELETE`, and `CREATE COLLECTION` statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, turbo, binary, product), SQL-style `WHERE` filters, script execution, and collection dump/restore.
|
|
11
11
|
|
|
12
12
|
```
|
|
13
13
|
qql> INSERT INTO COLLECTION notes VALUES {'text': 'Qdrant is a vector database', 'author': 'alice', 'year': 2024}
|
|
@@ -48,7 +48,7 @@ Your query string
|
|
|
48
48
|
Qdrant instance
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
When you run `INSERT`, the `text` field is automatically converted into a dense vector using [Fastembed](https://github.com/qdrant/fastembed). In **hybrid mode** (`USING HYBRID`), a sparse BM25 vector is also generated alongside the dense vector, and searches use Qdrant's Reciprocal Rank Fusion (RRF) to merge the results of both retrieval methods.
|
|
51
|
+
When you run `INSERT`, the `text` field is automatically converted into a dense vector using [Fastembed](https://github.com/qdrant/fastembed). In **hybrid mode** (`USING HYBRID`), a sparse BM25 vector is also generated alongside the dense vector, and searches use Qdrant's Reciprocal Rank Fusion (RRF) by default to merge the results of both retrieval methods. You can switch hybrid search to DBSF with `FUSION 'dbsf'`.
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -82,9 +82,9 @@ Full documentation lives in the [`docs/`](docs/) folder and at **[pavanjava.gith
|
|
|
82
82
|
|---|---|
|
|
83
83
|
| [Getting Started](docs/getting-started.md) | Installation, connecting, first queries |
|
|
84
84
|
| [INSERT / INSERT BULK](docs/insert.md) | Adding documents, batch inserts, payload types |
|
|
85
|
-
| [SEARCH / RECOMMEND / Hybrid / RERANK](docs/search.md) | Semantic search, hybrid, reranking, recommendations |
|
|
85
|
+
| [SEARCH / SELECT / SCROLL / RECOMMEND / Hybrid / RERANK](docs/search.md) | Semantic search, point retrieval, pagination, hybrid, reranking, recommendations |
|
|
86
86
|
| [WHERE Filters](docs/filters.md) | Full SQL-style filter operators |
|
|
87
|
-
| [Collections & Quantization](docs/collections.md) | CREATE, DROP, QUANTIZE (scalar/binary/product), CREATE INDEX |
|
|
87
|
+
| [Collections & Quantization](docs/collections.md) | CREATE, DROP, QUANTIZE (scalar/turbo/binary/product), CREATE INDEX |
|
|
88
88
|
| [Scripts: EXECUTE / DUMP](docs/scripts.md) | Script files, collection backup/restore |
|
|
89
89
|
| [Programmatic Usage](docs/programmatic.md) | Use QQL as a Python library |
|
|
90
90
|
| [Reference: Models / Config / Errors](docs/reference.md) | Embedding models, config file, error reference |
|
|
@@ -102,15 +102,27 @@ INSERT BULK INTO COLLECTION articles VALUES [{'text': '...'}, {'text': '...'}]
|
|
|
102
102
|
SEARCH articles SIMILAR TO 'query' LIMIT 10
|
|
103
103
|
SEARCH articles SIMILAR TO 'query' LIMIT 10 WHERE year >= 2020
|
|
104
104
|
SEARCH articles SIMILAR TO 'query' LIMIT 10 USING HYBRID
|
|
105
|
+
SEARCH articles SIMILAR TO 'query' LIMIT 10 USING HYBRID FUSION 'dbsf'
|
|
105
106
|
SEARCH articles SIMILAR TO 'query' LIMIT 10 USING HYBRID RERANK
|
|
106
107
|
|
|
108
|
+
-- Scroll
|
|
109
|
+
SCROLL FROM articles LIMIT 50
|
|
110
|
+
SCROLL FROM articles WHERE year >= 2024 LIMIT 50
|
|
111
|
+
SCROLL FROM articles AFTER 'cursor-id' LIMIT 50
|
|
112
|
+
|
|
107
113
|
-- Recommend
|
|
108
114
|
RECOMMEND FROM articles POSITIVE IDS (1001, 1002) LIMIT 5
|
|
109
115
|
|
|
116
|
+
-- Select (retrieve a point by ID)
|
|
117
|
+
SELECT * FROM articles WHERE id = '3f2e1a4b-...'
|
|
118
|
+
|
|
110
119
|
-- Collections
|
|
111
120
|
CREATE COLLECTION articles
|
|
112
121
|
CREATE COLLECTION articles HYBRID
|
|
113
122
|
CREATE COLLECTION articles QUANTIZE SCALAR
|
|
123
|
+
CREATE COLLECTION articles QUANTIZE TURBO
|
|
124
|
+
CREATE COLLECTION articles QUANTIZE TURBO BITS 2
|
|
125
|
+
CREATE COLLECTION articles QUANTIZE TURBO BITS 1.5 ALWAYS RAM
|
|
114
126
|
CREATE INDEX ON COLLECTION articles FOR year TYPE integer
|
|
115
127
|
SHOW COLLECTIONS
|
|
116
128
|
DROP COLLECTION articles
|
|
@@ -134,7 +146,7 @@ Tests do not require a running Qdrant instance — the Qdrant client is mocked.
|
|
|
134
146
|
pytest tests/ -v
|
|
135
147
|
```
|
|
136
148
|
|
|
137
|
-
Expected: **
|
|
149
|
+
Expected: **405 tests passing**.
|
|
138
150
|
|
|
139
151
|
---
|
|
140
152
|
|
|
@@ -67,27 +67,38 @@ When `USING MODEL` is omitted, the collection uses the **default embedding model
|
|
|
67
67
|
|
|
68
68
|
## Quantization — QUANTIZE clause
|
|
69
69
|
|
|
70
|
-
Quantization reduces the memory footprint of vector collections and speeds up search at the cost of a small, controllable accuracy loss. QQL supports all
|
|
70
|
+
Quantization reduces the memory footprint of vector collections and speeds up search at the cost of a small, controllable accuracy loss. QQL supports all four Qdrant quantization strategies via an optional `QUANTIZE` clause appended to `CREATE COLLECTION`.
|
|
71
71
|
|
|
72
|
-
**
|
|
72
|
+
**Four strategies:**
|
|
73
73
|
|
|
74
|
-
| Type | Compression | Accuracy
|
|
74
|
+
| Type | Compression | Accuracy | Best For |
|
|
75
75
|
|---|---|---|---|
|
|
76
|
-
| `SCALAR` | 4× (float32 → int8) | < 1% | Most collections — best balance |
|
|
77
|
-
| `
|
|
76
|
+
| `SCALAR` | 4× (float32 → int8) | < 1% loss | Most collections — best balance |
|
|
77
|
+
| `TURBO` | 8–32× (4-bit to 1-bit) | Low–medium | Better recall than BINARY at same storage budget |
|
|
78
|
+
| `BINARY` | 32× (float32 → 1-bit) | Higher loss | Speed priority; centered distributions only |
|
|
78
79
|
| `PRODUCT` | 4× (configurable) | Variable | Memory-constrained deployments |
|
|
79
80
|
|
|
80
81
|
**Full syntax:**
|
|
81
82
|
```
|
|
82
83
|
CREATE COLLECTION <name> ... QUANTIZE SCALAR [QUANTILE <0.0–1.0>] [ALWAYS RAM]
|
|
84
|
+
CREATE COLLECTION <name> ... QUANTIZE TURBO [BITS <1|1.5|2|4>] [ALWAYS RAM]
|
|
83
85
|
CREATE COLLECTION <name> ... QUANTIZE BINARY [ALWAYS RAM]
|
|
84
86
|
CREATE COLLECTION <name> ... QUANTIZE PRODUCT [ALWAYS RAM]
|
|
85
87
|
```
|
|
86
88
|
|
|
87
|
-
- **`QUANTILE <float>`** — (
|
|
88
|
-
- **`
|
|
89
|
+
- **`QUANTILE <float>`** — (SCALAR only) calibration quantile for the INT8 conversion; defaults to Qdrant's built-in default (0.99) when omitted.
|
|
90
|
+
- **`BITS <depth>`** — (TURBO only) bit depth passed to the Qdrant SDK:
|
|
91
|
+
- `4` — 4-bit (default when `BITS` is omitted; server applies its own default)
|
|
92
|
+
- `2` — 2-bit
|
|
93
|
+
- `1.5` — 1.5-bit
|
|
94
|
+
- `1` — 1-bit
|
|
95
|
+
> Compression ratios (8×, 16×, 24×, 32×) and recall characteristics are
|
|
96
|
+
> Qdrant server-side behaviors. QQL maps the `BITS` value to the SDK model and
|
|
97
|
+
> passes it to Qdrant; actual results depend on your Qdrant server version.
|
|
98
|
+
- **`ALWAYS RAM`** — keep the **quantized** vectors in RAM at all times, regardless of the collection's `on_disk` setting. Improves search throughput at the cost of higher RAM usage for the compressed index. The original full-precision vectors are stored and managed independently of this flag. Supported by all four quantization types.
|
|
89
99
|
- **`QUANTIZE`** always appears **after** all other clauses (`HYBRID`, `USING MODEL`, etc.).
|
|
90
100
|
- For `PRODUCT`, the compression ratio is fixed at **4×** in this version.
|
|
101
|
+
- For `TURBO`, Cosine, Dot, and Euclidean distance are supported by the Qdrant server when TurboQuant is enabled.
|
|
91
102
|
- When used with `HYBRID` collections, quantization applies only to the **dense** vector.
|
|
92
103
|
|
|
93
104
|
**Examples:**
|
|
@@ -102,6 +113,26 @@ Scalar with explicit calibration and quantized vectors pinned to RAM:
|
|
|
102
113
|
CREATE COLLECTION research_papers QUANTIZE SCALAR QUANTILE 0.95 ALWAYS RAM
|
|
103
114
|
```
|
|
104
115
|
|
|
116
|
+
TurboQuant — default 4-bit (8× compression, good recall):
|
|
117
|
+
```sql
|
|
118
|
+
CREATE COLLECTION research_papers QUANTIZE TURBO
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
TurboQuant — 2-bit (16× compression):
|
|
122
|
+
```sql
|
|
123
|
+
CREATE COLLECTION research_papers QUANTIZE TURBO BITS 2
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
TurboQuant — 1.5-bit (24× compression) with quantized vectors pinned to RAM:
|
|
127
|
+
```sql
|
|
128
|
+
CREATE COLLECTION research_papers QUANTIZE TURBO BITS 1.5 ALWAYS RAM
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
TurboQuant — 1-bit (32× compression, same ratio as BINARY but better recall):
|
|
132
|
+
```sql
|
|
133
|
+
CREATE COLLECTION research_papers QUANTIZE TURBO BITS 1
|
|
134
|
+
```
|
|
135
|
+
|
|
105
136
|
Binary quantization for large high-dimensional embeddings:
|
|
106
137
|
```sql
|
|
107
138
|
CREATE COLLECTION research_papers QUANTIZE BINARY
|
|
@@ -115,22 +146,29 @@ CREATE COLLECTION research_papers QUANTIZE PRODUCT ALWAYS RAM
|
|
|
115
146
|
Combined with hybrid collection:
|
|
116
147
|
```sql
|
|
117
148
|
CREATE COLLECTION research_papers HYBRID QUANTIZE SCALAR
|
|
149
|
+
CREATE COLLECTION research_papers HYBRID QUANTIZE TURBO BITS 2
|
|
118
150
|
```
|
|
119
151
|
|
|
120
152
|
Combined with a pinned model:
|
|
121
153
|
```sql
|
|
122
154
|
CREATE COLLECTION research_papers USING MODEL 'BAAI/bge-base-en-v1.5' QUANTIZE SCALAR QUANTILE 0.99
|
|
155
|
+
CREATE COLLECTION research_papers USING MODEL 'BAAI/bge-base-en-v1.5' QUANTIZE TURBO BITS 2
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Combined with hybrid + dense model:
|
|
159
|
+
```sql
|
|
160
|
+
CREATE COLLECTION research_papers USING HYBRID DENSE MODEL 'BAAI/bge-base-en-v1.5' QUANTIZE TURBO
|
|
123
161
|
```
|
|
124
162
|
|
|
125
163
|
**Valid combinations:**
|
|
126
164
|
|
|
127
|
-
| Base form | +
|
|
128
|
-
|
|
129
|
-
| `CREATE COLLECTION name` | ✓ | ✓ | ✓ |
|
|
130
|
-
| `... HYBRID` | ✓ | ✓ | ✓ |
|
|
131
|
-
| `... USING MODEL 'x'` | ✓ | ✓ | ✓ |
|
|
132
|
-
| `... USING HYBRID` | ✓ | ✓ | ✓ |
|
|
133
|
-
| `... USING HYBRID DENSE MODEL 'x'` | ✓ | ✓ | ✓ |
|
|
165
|
+
| Base form | + SCALAR | + TURBO | + BINARY | + PRODUCT |
|
|
166
|
+
|---|---|---|---|---|
|
|
167
|
+
| `CREATE COLLECTION name` | ✓ | ✓ | ✓ | ✓ |
|
|
168
|
+
| `... HYBRID` | ✓ | ✓ | ✓ | ✓ |
|
|
169
|
+
| `... USING MODEL 'x'` | ✓ | ✓ | ✓ | ✓ |
|
|
170
|
+
| `... USING HYBRID` | ✓ | ✓ | ✓ | ✓ |
|
|
171
|
+
| `... USING HYBRID DENSE MODEL 'x'` | ✓ | ✓ | ✓ | ✓ |
|
|
134
172
|
|
|
135
173
|
> INSERT and SEARCH on quantized collections work exactly the same as on non-quantized ones — no changes to INSERT or SEARCH syntax are needed.
|
|
136
174
|
|
|
@@ -24,7 +24,7 @@ Your query string
|
|
|
24
24
|
Qdrant instance
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
When you run `INSERT`, the `text` field is automatically converted into a dense vector using [Fastembed](https://github.com/qdrant/fastembed). In **hybrid mode** (`USING HYBRID`), a sparse BM25 vector is also generated alongside the dense vector, and searches use Qdrant's Reciprocal Rank Fusion (RRF) to merge the results of both retrieval methods.
|
|
27
|
+
When you run `INSERT`, the `text` field is automatically converted into a dense vector using [Fastembed](https://github.com/qdrant/fastembed). In **hybrid mode** (`USING HYBRID`), a sparse BM25 vector is also generated alongside the dense vector, and searches use Qdrant's Reciprocal Rank Fusion (RRF) by default to merge the results of both retrieval methods. You can override that with `FUSION 'dbsf'` on hybrid searches.
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
@@ -138,8 +138,14 @@ SEARCH notes SIMILAR TO 'vector storage engines' LIMIT 3
|
|
|
138
138
|
-- Filter results
|
|
139
139
|
SEARCH notes SIMILAR TO 'vector databases' LIMIT 5 WHERE year >= 2023
|
|
140
140
|
|
|
141
|
+
-- Browse with pagination
|
|
142
|
+
SCROLL FROM notes LIMIT 10
|
|
143
|
+
|
|
141
144
|
-- List all collections
|
|
142
145
|
SHOW COLLECTIONS
|
|
146
|
+
|
|
147
|
+
-- Retrieve a point by ID
|
|
148
|
+
SELECT * FROM notes WHERE id = 1
|
|
143
149
|
```
|
|
144
150
|
|
|
145
151
|
---
|
|
@@ -147,7 +153,7 @@ SHOW COLLECTIONS
|
|
|
147
153
|
## Next Steps
|
|
148
154
|
|
|
149
155
|
- [INSERT / INSERT BULK](insert.md) — adding documents
|
|
150
|
-
- [SEARCH / RECOMMEND / Hybrid / RERANK](search.md) — querying
|
|
156
|
+
- [SEARCH / SELECT / SCROLL / RECOMMEND / Hybrid / RERANK](search.md) — querying
|
|
151
157
|
- [WHERE Filters](filters.md) — payload filtering
|
|
152
158
|
- [Collections & Quantization](collections.md) — managing collections
|
|
153
159
|
- [Scripts: EXECUTE / DUMP](scripts.md) — automating with script files
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
<a href="https://pypi.org/project/qql-cli/"><img src="https://img.shields.io/pypi/v/qql-cli?color=blue&label=PyPI" alt="PyPI version" /></a>
|
|
115
115
|
<a href="https://pypi.org/project/qql-cli/"><img src="https://img.shields.io/pypi/pyversions/qql-cli" alt="Python versions" /></a>
|
|
116
116
|
<a href="https://github.com/pavanjava/qql/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License" /></a>
|
|
117
|
-
<a href="https://github.com/pavanjava/qql/actions"><img src="https://img.shields.io/badge/tests-
|
|
117
|
+
<a href="https://github.com/pavanjava/qql/actions"><img src="https://img.shields.io/badge/tests-405%20passing-brightgreen" alt="405 tests" /></a>
|
|
118
118
|
</div>
|
|
119
119
|
|
|
120
120
|
<pre><span class="cmt"># Install</span>
|
|
@@ -148,8 +148,8 @@
|
|
|
148
148
|
<p>Adding documents, batch inserts, payload types</p>
|
|
149
149
|
</a>
|
|
150
150
|
<a class="card" href="search">
|
|
151
|
-
<h3>SEARCH / RECOMMEND</h3>
|
|
152
|
-
<p>Semantic search, hybrid search, reranking, recommendations</p>
|
|
151
|
+
<h3>SEARCH / SELECT / SCROLL / RECOMMEND</h3>
|
|
152
|
+
<p>Semantic search, point retrieval, pagination, hybrid search, reranking, recommendations</p>
|
|
153
153
|
</a>
|
|
154
154
|
<a class="card" href="filters">
|
|
155
155
|
<h3>WHERE Filters</h3>
|
|
@@ -40,6 +40,15 @@ result = run_query(
|
|
|
40
40
|
for hit in result.data:
|
|
41
41
|
print(hit["score"], hit["payload"])
|
|
42
42
|
|
|
43
|
+
# Scroll / pagination
|
|
44
|
+
result = run_query(
|
|
45
|
+
"SCROLL FROM notes LIMIT 2",
|
|
46
|
+
url="http://localhost:6333",
|
|
47
|
+
)
|
|
48
|
+
for point in result.data["points"]:
|
|
49
|
+
print(point["id"], point["payload"])
|
|
50
|
+
print(result.data["next_offset"])
|
|
51
|
+
|
|
43
52
|
# Bulk insert (all records embedded and upserted in one call)
|
|
44
53
|
result = run_query(
|
|
45
54
|
"""INSERT BULK INTO COLLECTION notes VALUES [
|
|
@@ -58,6 +67,13 @@ result = run_query(
|
|
|
58
67
|
for hit in result.data:
|
|
59
68
|
print(hit["score"], hit["payload"])
|
|
60
69
|
|
|
70
|
+
# Retrieve a point by ID
|
|
71
|
+
result = run_query(
|
|
72
|
+
"SELECT * FROM notes WHERE id = 1",
|
|
73
|
+
url="http://localhost:6333",
|
|
74
|
+
)
|
|
75
|
+
print(result.data) # {"id": "1", "payload": {...}}
|
|
76
|
+
|
|
61
77
|
# Delete by filter
|
|
62
78
|
result = run_query(
|
|
63
79
|
"DELETE FROM notes WHERE year < 2023",
|
|
@@ -111,7 +127,9 @@ class ExecutionResult:
|
|
|
111
127
|
| INSERT (dense) | `{"id": int \| "<uuid>", "collection": "<name>"}` |
|
|
112
128
|
| INSERT (hybrid) | `{"id": int \| "<uuid>", "collection": "<name>"}` |
|
|
113
129
|
| INSERT BULK | `None` (count in `result.message`) |
|
|
130
|
+
| SELECT | `{"id": str, "payload": dict}` or `None` when not found |
|
|
114
131
|
| SEARCH | `[{"id": str, "score": float, "payload": dict}, ...]` |
|
|
132
|
+
| SCROLL | `{"points": [{"id": str, "payload": dict}, ...], "next_offset": str \| None}` |
|
|
115
133
|
| RECOMMEND | `[{"id": str, "score": float, "payload": dict}, ...]` |
|
|
116
134
|
| SHOW COLLECTIONS | `["name1", "name2", ...]` |
|
|
117
135
|
| CREATE COLLECTION | `None` |
|
|
@@ -36,6 +36,9 @@ SEARCH docs SIMILAR TO 'hello' LIMIT 5 USING MODEL 'BAAI/bge-small-en-v1.5'
|
|
|
36
36
|
-- Hybrid with custom dense model
|
|
37
37
|
SEARCH docs SIMILAR TO 'hello' LIMIT 5 USING HYBRID DENSE MODEL 'BAAI/bge-base-en-v1.5'
|
|
38
38
|
|
|
39
|
+
-- Hybrid with explicit fusion strategy
|
|
40
|
+
SEARCH docs SIMILAR TO 'hello' LIMIT 5 USING HYBRID FUSION 'dbsf'
|
|
41
|
+
|
|
39
42
|
-- Hybrid with both custom
|
|
40
43
|
SEARCH docs SIMILAR TO 'hello' LIMIT 5
|
|
41
44
|
USING HYBRID DENSE MODEL 'BAAI/bge-base-en-v1.5' SPARSE MODEL 'prithivida/Splade_PP_en_v1'
|
|
@@ -159,7 +162,7 @@ Tests do not require a running Qdrant instance — the Qdrant client is mocked.
|
|
|
159
162
|
pytest tests/ -v
|
|
160
163
|
```
|
|
161
164
|
|
|
162
|
-
Expected output: **
|
|
165
|
+
Expected output: **405 tests passing**.
|
|
163
166
|
|
|
164
167
|
---
|
|
165
168
|
|
|
@@ -171,12 +174,14 @@ Expected output: **375 tests passing**.
|
|
|
171
174
|
| `Connection failed: ...` | Qdrant unreachable at given URL | Check that Qdrant is running and the URL is correct |
|
|
172
175
|
| `INSERT requires a 'text' field in VALUES` | `text` key missing from the VALUES dict | Add `'text': '...'` to your dict |
|
|
173
176
|
| `Vector dimension mismatch: collection '...' expects X dims, but model produces Y dims` | Model used in INSERT differs from the one used to create the collection | Use `USING MODEL` to specify the same model as the collection was created with |
|
|
174
|
-
| `Collection '...' does not exist` | SEARCH / DROP / DELETE on a non-existent collection | Check name spelling or run `SHOW COLLECTIONS` |
|
|
175
|
-
| `Unexpected token '...'; expected a QQL statement keyword` | Unrecognized statement | Check the query syntax
|
|
177
|
+
| `Collection '...' does not exist` | SEARCH / SCROLL / SELECT / DROP / DELETE on a non-existent collection | Check name spelling or run `SHOW COLLECTIONS` |
|
|
178
|
+
| `Unexpected token '...'; expected a QQL statement keyword` | Unrecognized statement | Check the query syntax and supported statement list |
|
|
179
|
+
| `SELECT requires a string or integer point id, got '...'` | `SELECT` used with a non-ID filter value | Use `SELECT * FROM <collection> WHERE id = '<id>'` or an integer ID |
|
|
176
180
|
| `Unterminated string literal (at position N)` | A string is missing its closing quote | Close the string with a matching `'` or `"` |
|
|
177
181
|
| `Unexpected character '@' (at position N)` | A character not part of QQL syntax | Remove or quote the offending character |
|
|
178
182
|
| `Expected a filter operator after field '...'` | Unknown operator in WHERE clause | Use one of: `=`, `!=`, `>`, `>=`, `<`, `<=`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL`, `IS EMPTY`, `IS NOT EMPTY`, `MATCH` |
|
|
179
183
|
| `Expected ')' ...` | Unclosed parenthesis in WHERE clause | Add the missing `)` to close the group |
|
|
180
184
|
| `Qdrant error during SEARCH: ...` | Hybrid search on a non-hybrid collection, or wrong vector names | Ensure the collection was created with `HYBRID` before using `USING HYBRID` in INSERT/SEARCH |
|
|
185
|
+
| `Qdrant error during SCROLL: ...` | Qdrant rejected scroll request | Verify collection state, filter, and cursor (`AFTER`) value |
|
|
181
186
|
| `Unknown index type '...'` | Invalid schema type in CREATE INDEX | Use one of: `keyword`, `integer`, `float`, `bool`, `text`, `geo`, `datetime` |
|
|
182
187
|
| `Qdrant error during CREATE INDEX: ...` | Qdrant rejected the index creation | Check field name and collection state |
|
|
@@ -79,6 +79,9 @@ Export every point in a collection to a `.qql` script file. The generated file i
|
|
|
79
79
|
**CLI usage:**
|
|
80
80
|
```bash
|
|
81
81
|
qql dump <collection_name> <output.qql>
|
|
82
|
+
|
|
83
|
+
# Override the default 50 points/INSERT BULK batch
|
|
84
|
+
qql dump <collection_name> <output.qql> --batch-size 200
|
|
82
85
|
```
|
|
83
86
|
|
|
84
87
|
**In-shell usage (inside the QQL REPL):**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SEARCH, RECOMMEND, Hybrid Search & Reranking
|
|
1
|
+
# SEARCH, SELECT, SCROLL, RECOMMEND, Hybrid Search & Reranking
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
@@ -14,7 +14,7 @@ SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n>
|
|
|
14
14
|
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> USING MODEL '<model_name>'
|
|
15
15
|
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> [USING MODEL '<model>'] WHERE <filter>
|
|
16
16
|
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> USING HYBRID
|
|
17
|
-
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> USING HYBRID [DENSE MODEL '<model>'] [SPARSE MODEL '<model>'] [WHERE <filter>]
|
|
17
|
+
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> USING HYBRID [FUSION 'rrf|dbsf'] [DENSE MODEL '<model>'] [SPARSE MODEL '<model>'] [WHERE <filter>]
|
|
18
18
|
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> USING SPARSE [MODEL '<sparse_model>']
|
|
19
19
|
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> EXACT
|
|
20
20
|
SEARCH <collection_name> SIMILAR TO '<query_text>' LIMIT <n> [USING ...] [WHERE <filter>] [RERANK] WITH { hnsw_ef: <n>, exact: true|false, acorn: true|false }
|
|
@@ -33,7 +33,7 @@ Search only papers published after 2020:
|
|
|
33
33
|
SEARCH articles SIMILAR TO 'deep learning' LIMIT 10 WHERE year > 2020
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Hybrid search (combines dense semantic + sparse BM25 keyword retrieval via RRF):
|
|
36
|
+
Hybrid search (combines dense semantic + sparse BM25 keyword retrieval via RRF by default):
|
|
37
37
|
```sql
|
|
38
38
|
SEARCH articles SIMILAR TO 'attention mechanism' LIMIT 10 USING HYBRID
|
|
39
39
|
```
|
|
@@ -70,6 +70,28 @@ Results are displayed as a table with three columns:
|
|
|
70
70
|
|
|
71
71
|
---
|
|
72
72
|
|
|
73
|
+
## SELECT — retrieve a point by ID
|
|
74
|
+
|
|
75
|
+
Fetches a single point payload by exact point ID.
|
|
76
|
+
|
|
77
|
+
**Syntax:**
|
|
78
|
+
```sql
|
|
79
|
+
SELECT * FROM <collection_name> WHERE id = '<point_id>'
|
|
80
|
+
SELECT * FROM <collection_name> WHERE id = <integer_id>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Examples:**
|
|
84
|
+
```sql
|
|
85
|
+
SELECT * FROM articles WHERE id = '3f2e1a4b-8c91-4d0e-b123-abc123def456'
|
|
86
|
+
SELECT * FROM articles WHERE id = 42
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`SELECT` in this version is intentionally strict:
|
|
90
|
+
- only `*` projection is supported
|
|
91
|
+
- only `WHERE id = ...` is supported
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
73
95
|
## Query-Time Search Params (`EXACT`, `WITH`)
|
|
74
96
|
|
|
75
97
|
Use these when you want to debug retrieval quality or tune recall without changing collection-level settings.
|
|
@@ -98,15 +120,41 @@ SEARCH articles SIMILAR TO 'RAG' LIMIT 10 WHERE tag = 'li' WITH { acorn: true }
|
|
|
98
120
|
|
|
99
121
|
---
|
|
100
122
|
|
|
123
|
+
## SCROLL — pagination / browsing
|
|
124
|
+
|
|
125
|
+
Use `SCROLL` to iterate through points in a collection page by page.
|
|
126
|
+
|
|
127
|
+
**Syntax:**
|
|
128
|
+
```sql
|
|
129
|
+
SCROLL FROM <collection_name> LIMIT <n>
|
|
130
|
+
SCROLL FROM <collection_name> WHERE <filter> LIMIT <n>
|
|
131
|
+
SCROLL FROM <collection_name> AFTER '<point_id>' LIMIT <n>
|
|
132
|
+
SCROLL FROM <collection_name> WHERE <filter> AFTER <point_id> LIMIT <n>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Examples:**
|
|
136
|
+
```sql
|
|
137
|
+
SCROLL FROM articles LIMIT 50
|
|
138
|
+
SCROLL FROM articles WHERE year >= 2024 LIMIT 50
|
|
139
|
+
SCROLL FROM articles AFTER 'cursor-id' LIMIT 50
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Behavior:**
|
|
143
|
+
- Returns points in ID order with payloads.
|
|
144
|
+
- Returns a `next_offset` cursor when more points are available.
|
|
145
|
+
- Use `AFTER <next_offset>` to fetch the next page.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
101
149
|
## Hybrid Search (USING HYBRID)
|
|
102
150
|
|
|
103
|
-
Hybrid search combines **dense semantic vectors** and **sparse BM25 keyword vectors** in a single query
|
|
151
|
+
Hybrid search combines **dense semantic vectors** and **sparse BM25 keyword vectors** in a single query. By default QQL merges the two result sets with Qdrant's **Reciprocal Rank Fusion (RRF)** algorithm, and you can optionally switch to **DBSF** with a `FUSION` clause.
|
|
104
152
|
|
|
105
153
|
### How it works internally
|
|
106
154
|
|
|
107
155
|
1. Both a dense vector (`TextEmbedding`) and a sparse BM25 vector (`SparseTextEmbedding`) are generated from your query text.
|
|
108
156
|
2. Qdrant fetches the top candidates from each index independently (`prefetch limit = LIMIT × 4`).
|
|
109
|
-
3. The two result lists are merged using
|
|
157
|
+
3. The two result lists are merged using the selected fusion strategy (`RRF` by default, or `DBSF` when requested).
|
|
110
158
|
4. The final top-N results are returned.
|
|
111
159
|
|
|
112
160
|
### Step 1: Create a hybrid collection
|
|
@@ -139,6 +187,9 @@ SEARCH articles SIMILAR TO 'transformer architecture' LIMIT 10 USING HYBRID
|
|
|
139
187
|
-- Hybrid search with a WHERE filter
|
|
140
188
|
SEARCH articles SIMILAR TO 'attention' LIMIT 10 USING HYBRID WHERE year >= 2017
|
|
141
189
|
|
|
190
|
+
-- Hybrid with DBSF fusion
|
|
191
|
+
SEARCH articles SIMILAR TO 'hybrid retrieval' LIMIT 10 USING HYBRID FUSION 'dbsf'
|
|
192
|
+
|
|
142
193
|
-- Hybrid with custom dense model
|
|
143
194
|
SEARCH articles SIMILAR TO 'embeddings' LIMIT 5
|
|
144
195
|
USING HYBRID DENSE MODEL 'BAAI/bge-base-en-v1.5'
|
|
@@ -154,6 +205,7 @@ SEARCH articles SIMILAR TO 'sparse retrieval' LIMIT 5
|
|
|
154
205
|
|---|---|
|
|
155
206
|
| Dense model | configured default (`sentence-transformers/all-MiniLM-L6-v2`) |
|
|
156
207
|
| Sparse model | `Qdrant/bm25` |
|
|
208
|
+
| Fusion | `rrf` |
|
|
157
209
|
|
|
158
210
|
### Dense vs. hybrid — when to use which
|
|
159
211
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "qql-cli"
|
|
3
|
-
version = "2.
|
|
4
|
-
description = "QQL is a SQL-like query language and CLI for Qdrant vector database. Write INSERT, SEARCH, RECOMMEND, DELETE, and CREATE COLLECTION statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, binary, product), WHERE clause filters, script execution, and collection dump/restore."
|
|
3
|
+
version = "2.2.0"
|
|
4
|
+
description = "QQL is a SQL-like query language and CLI for Qdrant vector database. Write INSERT, SEARCH, RECOMMEND, DELETE, and CREATE COLLECTION statements instead of Python SDK calls. Supports hybrid dense+sparse vector search, cross-encoder reranking, quantization (scalar, turbo, binary, product), WHERE clause filters, script execution, and collection dump/restore."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
7
7
|
requires-python = ">=3.12"
|
|
@@ -37,7 +37,7 @@ classifiers = [
|
|
|
37
37
|
"Topic :: Text Processing :: Indexing",
|
|
38
38
|
]
|
|
39
39
|
dependencies = [
|
|
40
|
-
"qdrant-client[fastembed]>=1.
|
|
40
|
+
"qdrant-client[fastembed]>=1.18.0",
|
|
41
41
|
"click>=8.1.0",
|
|
42
42
|
"rich>=13.0.0",
|
|
43
43
|
"prompt_toolkit>=3.0.0",
|
|
@@ -9,14 +9,16 @@ class QuantizationType(Enum):
|
|
|
9
9
|
SCALAR = "scalar"
|
|
10
10
|
BINARY = "binary"
|
|
11
11
|
PRODUCT = "product"
|
|
12
|
+
TURBO = "turbo"
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
@dataclass(frozen=True)
|
|
15
16
|
class QuantizationConfig:
|
|
16
17
|
"""Quantization settings parsed from a QUANTIZE clause."""
|
|
17
18
|
type: QuantizationType
|
|
18
|
-
quantile: float | None = None
|
|
19
|
-
always_ram: bool = False
|
|
19
|
+
quantile: float | None = None # SCALAR only; None → Qdrant default (0.99)
|
|
20
|
+
always_ram: bool = False # all types; default False
|
|
21
|
+
turbo_bits: float | None = None # TURBO only; None → bits4 (Qdrant default 4-bit, 8×)
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
@dataclass(frozen=True)
|
|
@@ -178,6 +180,20 @@ class ShowCollectionsStmt:
|
|
|
178
180
|
pass
|
|
179
181
|
|
|
180
182
|
|
|
183
|
+
@dataclass(frozen=True)
|
|
184
|
+
class SelectStmt:
|
|
185
|
+
collection: str
|
|
186
|
+
point_id: str | int
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@dataclass(frozen=True)
|
|
190
|
+
class ScrollStmt:
|
|
191
|
+
collection: str
|
|
192
|
+
limit: int
|
|
193
|
+
query_filter: FilterExpr | None = None
|
|
194
|
+
after: str | int | None = None
|
|
195
|
+
|
|
196
|
+
|
|
181
197
|
@dataclass(frozen=True)
|
|
182
198
|
class SearchStmt:
|
|
183
199
|
collection: str
|
|
@@ -185,6 +201,7 @@ class SearchStmt:
|
|
|
185
201
|
limit: int
|
|
186
202
|
model: str | None # dense model; None → use config default
|
|
187
203
|
hybrid: bool = False # if True, use prefetch+RRF hybrid search
|
|
204
|
+
fusion: str | None = None # hybrid fusion strategy; None → default rrf
|
|
188
205
|
sparse_only: bool = False # if True, query only the sparse vector (no dense)
|
|
189
206
|
sparse_model: str | None = None # sparse model for hybrid/sparse-only; None → SparseEmbedder.DEFAULT_MODEL
|
|
190
207
|
query_filter: FilterExpr | None = None # optional WHERE clause; default keeps existing tests valid
|
|
@@ -223,6 +240,8 @@ ASTNode = (
|
|
|
223
240
|
| CreateIndexStmt
|
|
224
241
|
| DropCollectionStmt
|
|
225
242
|
| ShowCollectionsStmt
|
|
243
|
+
| SelectStmt
|
|
244
|
+
| ScrollStmt
|
|
226
245
|
| SearchStmt
|
|
227
246
|
| RecommendStmt
|
|
228
247
|
| DeleteStmt
|