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

Install

opam install qdrant

Quick 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:

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:

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" count

Recommend 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

Health & Info

Collections

Points

Scroll & Count

Filter Module (Sum Types)

Filter Module (Fluent Helpers)

Inspiration

This client combines the best from official Qdrant clients:

Testing

Unit Tests (No Qdrant Required)

dune runtest

27 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.exe

Security

License

MIT