package qdrant
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
On This Page
OCaml client for Qdrant vector database
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.1.0.tar.gz
sha256=2c0da427ba3abaea8c96539c64243def00a0f3923d43631642f9617338ca6c79
doc/README.html
ocaml-qdrant
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
- Async I/O with Lwt
- Type-safe OCaml design
Install
opam install qdrantQuick Start
let () = Lwt_main.run begin
let open Lwt.Syntax in
let open Qdrant in
(* Create collection *)
let* _ = create_collection
~name:"my_collection"
~vector_config:{ size = 1024; distance = Cosine }
() in
(* Insert points *)
let* _ = upsert ~collection:"my_collection" ~points:[
{ id = "1"; vector = my_embedding; payload = [("text", `String "hello")] }
] () in
(* Search *)
let* results = search
~collection:"my_collection"
~vector:query_embedding
~limit:10
() in
Lwt.return ()
endFilter 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
~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
~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
~collection:"products"
~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 ~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 () 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
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
On This Page