package qdrant
All checked builds passInstall
dune-project
Dependency
Authors
Maintainers
Sources
md5=6bc0d2d10180d2e4a9664a87c75141da
sha512=f00e4cd13ed5cae1a992e42eb0c5e7db0cc898d88dcd9486a4f26a0a2190719d5ed118e45da601886756d2745b5295b76028c46ced0bf35dddb70e76664606e2
Description
Pure OCaml client for Qdrant REST API. Supports vector search, collection management, and point operations.
Added to opam-repository:
README
qdrant-ocaml
Pure OCaml client for Qdrant vector database.
The first OCaml Qdrant client! Combines best practices from official Python, Rust, Go, and TypeScript clients.
Features
- REST API client (no gRPC dependency)
- Collection management (create, delete, info, exists)
- Point operations (upsert, delete, get, batch upsert)
- Vector search with filters and score threshold
- Two Filter APIs: Sum types (explicit) + Fluent helpers (ergonomic)
- Batch operations with automatic chunking (Python-inspired)
- Recommend API with positive/negative examples
- Direct-style Async I/O with Eio (OCaml 5.x)
- Type-safe OCaml design
Install
opam install qdrantQuick Start
let () = Eio_main.run @@ fun env ->
Eio.Switch.run @@ fun sw ->
let net = Eio.Stdenv.net env in
let clock = Eio.Stdenv.clock env in
let open Qdrant in
(* Create collection *)
let _ = create_collection ~sw ~net ~clock
~name:"my_collection"
~vector_config:{ size = 1024; distance = Cosine }
() in
(* Insert points *)
let _ = upsert ~sw ~net ~clock ~collection:"my_collection" ~points:[
{ id = "1"; vector = my_embedding; payload = [("text", `String "hello")] }
] () in
(* Search *)
let results = search ~sw ~net ~clock
~collection:"my_collection"
~vector:query_embedding
~limit:10
() in
Printf.printf "Found %d results\n" (List.length results)Filter API
Two styles are available - choose based on your preference:
Style 1: Sum Types (Explicit, Pattern-matchable)
Direct use of algebraic data types. Best for:
- Pattern matching on filter conditions
- Compile-time exhaustiveness checking
- Maximum type safety
let open Qdrant.Filter in
(* Simple filter *)
let filter = Must [
MatchKeyword ("category", "tech");
Range ("price", { gt = None; gte = Some 10.0; lt = None; lte = Some 100.0 });
]
(* Complex filter with nesting *)
let filter = And [
Must [MatchKeyword ("status", "active")];
Should [
MatchAny ("tags", ["ai"; "ml"; "data"]);
GeoRadius ("location", { lat = 37.5; lon = 127.0 }, 1000.0);
];
MustNot [IsNull "deleted_at"];
]Style 2: Fluent Helpers (Ergonomic, Go/Rust-inspired)
Convenience functions wrapping sum types. Best for:
- Quick prototyping
- Cleaner syntax for common cases
- Familiar to Go/Rust developers
let open Qdrant.Filter in
(* Simple filter *)
let filter = must [
match_keyword "category" "tech";
range "price" ~gte:10.0 ~lte:100.0 ();
]
(* Complex filter *)
let filter = combine [
must [match_keyword "status" "active"];
should [
match_any "tags" ["ai"; "ml"; "data"];
geo_radius "location" ~lat:37.5 ~lon:127.0 ~radius_m:1000.0;
];
must_not [is_null "deleted_at"];
]
(* Full-text search *)
let filter = must [full_text "content" "machine learning"]
(* Null checks *)
let filter = must [is_not_null "required_field"]Both styles produce identical JSON and can be used with search_with_filter:
let results = search_with_filter ~sw ~net ~clock
~collection:"items"
~vector:query_vec
~limit:10
~filter:(Filter.to_json filter)
()Batch Operations
Python-inspired batch upsert with automatic chunking:
(* Insert 10,000 points in chunks of 100 *)
let count = batch_upsert ~sw ~net ~clock
~collection:"embeddings"
~points:large_point_list
~chunk_size:100
() in
Printf.printf "Inserted %d points\n" countRecommend API
Find similar items based on examples:
let recommendations = recommend ~sw ~net ~clock
~collection:"id_of_collection"
~positive:["liked-item-1"; "liked-item-2"]
~negative:["disliked-item"]
~limit:10
()Config
From Environment Variables (Recommended)
export QDRANT_URL="http://localhost:6333"
export QDRANT_API_KEY="your-api-key" # optional(* Explicit is better than implicit - use config_from_env *)
let config = Qdrant.config_from_env () in
let result = Qdrant.health ~sw ~net ~clock ~config () in
...Programmatic Configuration
let config = Qdrant.{
base_url = "https://your-qdrant.cloud";
api_key = Some "your-key";
timeout_s = 30.0;
}Default Config
(* default_config = localhost:6333, no API key, 30s timeout *)
let result = Qdrant.health ~sw ~net ~clock () in (* uses default_config *)API Reference
Configuration
default_config- Default config (localhost:6333, no API key)config_from_env- Create config from QDRANT_URL and QDRANT_API_KEY env vars
Health & Info
health- Check server statusversion- Get Qdrant version
Collections
list_collections- List all collectionscollection_exists- Check if collection existsget_collection- Get collection infocreate_collection- Create with vector configdelete_collection- Delete collection
Points
upsert- Insert/update pointsbatch_upsert- Bulk insert with chunkingdelete_points- Delete by IDsget_point- Get single point
Search
search- Vector similarity searchsearch_with_filter- Search with payload filterrecommend- Recommendation based on examples
Scroll & Count
scroll- Paginate through all pointscount- Count points in collection
Filter Module (Sum Types)
MatchKeyword,MatchAny,MatchInt,MatchBool,MatchTextRange,RangeIntIsNull,IsEmpty,HasValue,NotEmptyGeoRadiusMust,Should,MustNot,And
Filter Module (Fluent Helpers)
match_keyword,match_any,match_int,match_boolfull_textrange,range_intis_null,is_not_null,is_empty,is_not_emptygeo_radiusmust,should,must_not,combine
Inspiration
This client combines the best from official Qdrant clients:
- Python: Batch operations with chunking, comprehensive API
- Rust: Type safety, sum types for filters
- Go: Fluent filter API, builder patterns (qdrant-go)
- TypeScript: Clean async/await patterns
Testing
Unit Tests (No Qdrant Required)
dune runtest27 tests covering types, filters, config, and error handling.
Integration Tests (Qdrant Required)
# Set up environment
export QDRANT_URL="http://localhost:6333"
# or for cloud: export QDRANT_URL="https://your-cluster.qdrant.io"
# export QDRANT_API_KEY="your-key"
# Run integration example
dune exec examples/basic.exeSecurity
- Path injection prevention (validates collection names and IDs)
- HTTP header injection prevention (validates API keys)
- Timeout protection against hung connections
License
MIT
Dependencies (7)
Optional Dependencies
None
Used by
None
Conflicts
None
Build status
Results of building qdrant with each compiler on check.ci.ocaml.org, run of against opam-repository 7cdc698. All results for this package.
Each result links to its build log. To keep crawlers from overloading the site, build logs require a GitHub sign-in (see ocurrent/opam-health-check). On your first log, GitHub asks you to “Authorize opam-health-check”, the OCurrent app that runs these checks; it sees only your public profile, not your repositories. The sign-in lasts 30 days.
| Version | OCaml 4.11 | OCaml 4.14 | OCaml 5.2 | OCaml 5.4 | OCaml 5.5 |
|---|---|---|---|---|---|
| 0.2.0 (this version) | n/a | n/a | good | good | good |
| 0.1.0 | n/a | good | good | good | good |
- good Package successfully built
- partial One of the dependencies failed to build
- bad Package failed to build
- n/a Package is not available in this environment
- internal Internal failure