qql-cli
Command-line interface and interactive REPL for QQL. Connects to Qdrant, executes queries, converts REST payloads, dumps collections, and runs an in-process qdrant-edge backend.
Installation
# Default build (gRPC + REST)
# Full build with local edge execution
# REST-only (smaller binary)
# binary at target/release/qql
Commands
exec — Run a single QQL query
execute — Run multiple queries from a .qql script file
explain — Show execution plan without running
connect — Start interactive REPL
Opens a REPL connected to Qdrant:
Then type QQL directly:
qql> SHOW COLLECTIONS;
qql> QUERY 'similar to this' FROM docs LIMIT 10;
qql> UPSERT INTO docs (id, vector, payload) VALUES ...
qql> exit
Built-in REPL commands: help, explain <query>, execute <file>, dump <name> <file>, exit/quit.
convert — Convert Qdrant REST JSON payloads to QQL
Reads a REST JSON payload (from file or stdin) and outputs the equivalent QQL statement:
|
dump — Export a collection to .qql script
Full collection export as a replayable .qql script:
CREATE COLLECTIONreconstructed from live vector schema (size, distance, sparse)CREATE INDEXstatements from payload indexes (when reported by Qdrant)- Batched
UPSERTstatements with realvector:values (not re-embed stubs)
Uses cursor pagination (AFTER / next_page_offset) and requests vectors on every
scroll page. Safe for multi-batch collections and streams to disk.
Reload with:
doctor — Check Qdrant connection health + embedding hosts
Prints connectivity and which embedding/rerank hosts are configured:
| Flag | Meaning |
|---|---|
dense |
Dense text embedder model/endpoint present |
multi |
Multivector / ColBERT (multi_model or multi HTTP) |
image |
CLIP vision (image_model or image HTTP) |
cross_rerank |
Cross-encoder (reranker_model / rerank_endpoint) |
Missing multi/image/cross hosts include short config hints (features fail only when used if hosts are absent).
--edge — Run normal commands against local qdrant-edge
The edge backend is an optional feature because FastEmbed and ONNX materially increase compile time and binary size. Configure it once:
# Local ONNX embeddings
# Or an OpenAI-compatible HTTP embedder
Then select the configured backend with the global flag:
# Schema fills USING roles (dense/sparse/multi); offline/explicit: AS DENSE|SPARSE|MULTI
Configuration is stored at ~/.qql/edge.json. CLI selection has the normal
precedence: environment overrides the saved file, while --edge selects the
backend. Supported overrides are QQL_EDGE_DATA_DIR,
QQL_EDGE_ON_DISK, QQL_EDGE_EMBEDDER, QQL_EDGE_MODEL,
QQL_EDGE_CACHE_DIR, EMBED_URL, EMBED_KEY, EMBED_MODEL, and
EMBED_DIM.
version — Print version info
Configuration
# Global flag (overrides QDRANT_URL)
Set via environment variables:
| Variable | Default | Description |
|---|---|---|
QDRANT_URL |
http://localhost:6333 |
Qdrant REST/gRPC URL |
QDRANT_API_KEY |
— | Qdrant API key for authenticated access |
EMBED_URL |
— | HTTP embedder endpoint (Ollama, OpenAI, TEI, etc.) |
EMBED_KEY |
— | API key for HTTP embedder |
EMBED_MODEL |
all-minilm:l6-v2 |
Embedding model name |
EMBED_DIM |
384 |
Expected embedding dimension |
Persistent config loaded from ~/.qql/config.json (auto-created on first use). Fields mirror QqlConfig:
Optional multi / image / rerank endpoints mirror dense (multi_embedding_endpoint,
image_embedding_endpoint, rerank_endpoint). Edge offline models:
QQL_EDGE_MULTI_MODEL, QQL_EDGE_IMAGE_MODEL, QQL_EDGE_RERANKER_MODEL.
qql doctor reports which of dense / multi / image / cross_rerank are configured.
Feature Flags
| Feature | Default | Description |
|---|---|---|
rest |
yes | Qdrant REST API transport |
grpc |
yes | Qdrant gRPC transport (auto-selected when URL contains :6334) |
edge |
no | In-process qdrant-edge backend and local FastEmbed inference |
.qql Script Format
Statements are separated by semicolons. Supports all QQL statements:
CREATE COLLECTION docs WITH VECTOR size 384 distance Cosine;
UPSERT INTO docs (id, vector, payload) VALUES
(1, [0.1, 0.2, ...], {"text": "first document"}),
(2, [0.3, 0.4, ...], {"text": "second document"});
QUERY 'search' FROM docs LIMIT 10;
Comments with -- and blank lines are ignored.