Sign in

    moon-qdrant

    A MoonBit client for the Qdrant vector database REST API.

    qdrant
    vector-database
    client
    rag
    embedding
    Download zip
    Author
    Version
    0.4.1
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    44

    #yuzhiblue/moon-qdrant

    CI Integration

    A MoonBit client for the Qdrant vector database REST API.

    moon-qdrant lets MoonBit programs manage Qdrant collections, upsert points, and run vector searches without leaving the MoonBit ecosystem. It is built on oboard/mio for HTTP transport and the MoonBit core JSON library.

    #Why

    Qdrant is one of the most widely used vector databases for RAG and embedding search. The MoonBit ecosystem already has vector engines and servers (e.g. trkbt10/vcdb), but no client library to talk to a running Qdrant service. moon-qdrant fills that gap with a small, explicit API surface that maps 1:1 to Qdrant REST endpoints.

    #Install

    moon add yuzhiblue/moon-qdrant

    #Quick start

    Start a local Qdrant server (Docker):

    docker run -p 6333:6333 qdrant/qdrant

    Then use the client:

    let client = QdrantClient::new("http://localhost:6333")

    // health check
    let ok = client.health()

    // create a collection with 4-dimensional cosine vectors
    client.create_collection(
    "demo",
    CollectionConfig::new(VectorParams::new(4, Distance::Cosine)),
    )

    // list collections
    let names = client.list_collections()

    // inspect a collection
    let info = client.collection_info("demo")

    // does it exist?
    let exists = client.collection_exists("demo")

    // write some points
    client.upsert_points("demo", [
    PointStruct::new(1, [0.1, 0.2, 0.3, 0.4], { "tag": "alpha" }),
    PointStruct::new(2, [0.5, 0.6, 0.7, 0.8], { "tag": "beta" }),
    ])

    // read one back
    let point = client.get_point("demo", 1)

    // search for the most similar points
    let hits = client.search_points("demo", [0.1, 0.2, 0.3, 0.4], limit=2)

    // search with a payload filter
    let filtered = client.search_points(
    "demo",
    [0.1, 0.2, 0.3, 0.4],
    limit=2,
    filter={ "must": [{ "key": "tag", "match": { "value": "alpha" } }] },
    )

    // delete points by id
    client.delete_points("demo", [2])

    // drop the collection
    client.delete_collection("demo")

    search_points accepts optional score_threshold (keep only hits above a score), offset (pagination), using_vector (pick a named vector to query against) and search_params (HNSW tuning / exact search):

    // only hits scoring 0.9 or better, skipping the first hit

    ///|
    let hits = client.search_points(
    "demo",
    [0.1, 0.2, 0.3, 0.4],
    2,
    score_threshold=Some(0.9),
    offset=Some(1),
    search_params=Some(SearchParams::new(exact=Some(true))),
    )

    // several searches in one round trip

    ///|
    let batch = client.search_points_batch("demo", [
    { "vector": [0.1, 0.2, 0.3, 0.4], "limit": 2 },
    { "vector": [0.9, 0.8, 0.7, 0.6], "limit": 2 },
    ])

    #Named vectors

    Qdrant collections can store several vectors per point. moon-qdrant supports this end to end: create the collection with named configurations, upsert points with several vectors, and search against one of them.

    let named : Map[String, VectorParams] = Map([])
    named["text"] = VectorParams::new(4, Distance::Cosine)
    named["image"] = VectorParams::new(8, Distance::Dot)
    client.create_collection("multi", CollectionConfig::new_named(named))

    let vectors : Map[String, Array[Double]] = Map([])
    vectors["text"] = [0.1, 0.2, 0.3, 0.4]
    vectors["image"] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
    client.upsert_points("multi", [PointStruct::new_named(1, vectors, { "tag": "a" })])

    // search against the "text" vector
    let hits = client.search_points(
    "multi",
    [0.1, 0.2, 0.3, 0.4],
    1,
    using_vector=Some("text"),
    )
    // or via a NamedVector input
    let hits = client.search_points_named(
    "multi",
    NamedVector::new("image", [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]),
    1,
    )

    #Payload management

    // merge fields into the payload of points 1 and 2
    client.set_payload("demo", { "active": true }, ids=Some([1, 2]))
    // replace the whole payload of points matching a filter
    client.overwrite_payload(
    "demo",
    { "state": "new" },
    filter=Some(Filter::new().must(Condition::match_keyword("tag", "alpha"))),
    )
    // drop selected keys from point 1
    client.delete_payload_by_keys("demo", ["active"], ids=Some([1]))
    // drop the whole payload of all points matching a filter
    client.delete_payload("demo", filter=Some(Filter::new()))

    #Query API and facets

    The Qdrant query API (POST /collections/{name}/points/query) is exposed through query_nearest (nearest neighbor) and query_recommend (recommendation from positive / negative examples), plus a raw query_points for advanced queries:

    // nearest neighbor
    let hits = client.query_nearest("demo", [0.1, 0.2, 0.3, 0.4], 2)

    // recommendation: like the positive vectors, unlike the negative ones
    let positive : Array[Json] = [
    Json::array([0.1, 0.2, 0.3, 0.4]),
    Json::number(3), // point ids are accepted too
    ]
    let negative : Array[Json] = [Json::array([0.9, 0.8, 0.7, 0.6])]
    let recs = client.query_recommend(
    "demo",
    positive,
    negative=Some(negative),
    limit=5,
    )

    // facet: how many points carry each distinct value of a payload field
    let facet = client.facet_points("demo", "tag", 10)
    for hit in facet.hits {
    println(hit.value.stringify() + ": " + hit.count.to_string())
    }

    // grouped search: top hits per distinct payload value
    let groups = client.search_points_groups(
    "demo",
    [0.1, 0.2, 0.3, 0.4],
    2, // hits per group
    "tag", // group-by field
    10, // max groups
    )
    for group in groups {
    println(
    "group " + group.id.stringify() + " -> " +
    group.hits.length().to_string() + " hits",
    )
    }

    #Cluster, locks and server info

    // cluster state (works on single-node deployments too)
    let cluster = client.cluster_info()
    println("cluster status: " + cluster.status)
    println("peers: " + cluster.peers.length().to_string())

    // per-collection shard / replica layout
    let layout = client.collection_cluster_info("demo")
    for shard in layout.local_shards {
    println(
    "shard " + shard.shard_id.to_string() + ": " +
    shard.state + " (" + shard.points_count.to_string() + " points)",
    )
    }

    // shard lifecycle (multi-node clusters)
    client.replicate_shard("demo", 0L, 1L, 2L)
    client.create_shard_replica("demo", 0L, 2L)
    client.delete_shard_replica("demo", 0L, 2L)

    // write lock + server version
    client.set_locks(true, error_message=Some("maintenance"))
    let lock = client.get_locks()
    println("writes locked: " + lock.write.to_string())
    let info = client.service_info()
    match info.version {
    Some(v) => println("qdrant version: " + v)
    None => ()
    }

    #Collection updates, payload indexes and snapshots

    // update replication settings
    client.update_collection(
    "demo",
    CollectionUpdate::new(replication_factor=Some(2)),
    )

    // index a payload field for fast filtered access
    client.create_payload_index("demo", "tag", "keyword")
    let indexes = client.list_payload_indexes("demo")
    client.delete_payload_index("demo", "tag")

    // snapshot the collection for backup / migration
    let snap = client.create_snapshot("demo")
    let snapshots = client.list_snapshots("demo")
    client.delete_snapshot("demo", snap.name)

    #Examples

    Health-check CLI (needs a running Qdrant server):

    moon run cmd/main -- http://localhost:6333

    End-to-end demo: create collection, upsert points, search (with and without a payload filter), read a point, delete points, drop the collection:

    docker run -p 6333:6333 qdrant/qdrant moon run examples/demo -- http://localhost:6333

    #Status / roadmap

    Implemented:

    Planned:

    #Development

    moon check --deny-warn moon test moon fmt

    #Integration testing against a real Qdrant

    Unit tests cover the pure logic (models, JSON conversion, request bodies). The end-to-end path is verified in CI against a real Qdrant server (.github/workflows/integration.yml starts a qdrant/qdrant container and runs examples/integration_check, which asserts every client method against the live API, then runs the demo end to end).

    Locally, start Qdrant and run the same checks:

    docker run -p 6333:6333 qdrant/qdrant moon run examples/integration_check -- http://localhost:6333 moon run examples/demo -- http://localhost:6333

    #License

    Apache-2.0

    VectorProvider

    pub trait VectorProvider {
    async fn create_collection(self : Self, name : String, config : CollectionConfig) -> Unit
    async fn delete_collection(self : Self, name : String) -> Unit
    async fn collection_exists(self : Self, name : String) -> Bool
    async fn upsert_points(self : Self, name : String, points : Array[PointStruct]) -> Unit
    async fn upsert_points_batch(self : Self, name : String, points : Array[PointStruct]) -> Unit
    async fn search_points(self : Self, name : String, vector : Array[Double], limit : Int, filter? : Json?) -> Array[ScoredPoint]
    async fn search_with_filter(self : Self, name : String, vector : Array[Double], limit : Int, filter : Filter) -> Array[ScoredPoint]
    }

    A common interface implemented by vector-service clients.

    QdrantClient implements this trait. The trait exists so that higher-level code (RAG pipelines, embedding indexes) can be written against one shape and later switch to another vector service without changing call sites.

    AliasInfo

    pub struct AliasInfo {
    alias_name : String
    collection_name : String
    }

    One collection alias entry, as returned by GET /collections/aliases.

    AliasInfo::from_json

    fn AliasInfo::from_json(json : Json) -> AliasInfo?

    Parse one alias entry: { "alias_name": "prod", "collection_name": "demo" }.

    ClusterInfo

    pub struct ClusterInfo {
    status : String
    peer_id : Int64
    peers : Map[String, PeerInfo]
    raft_info : RaftInfo?
    }

    Overall cluster state, from GET /cluster.

    ClusterInfo::from_json

    fn ClusterInfo::from_json(json : Json) -> ClusterInfo?

    Parse the cluster info result object.

    CollectionClusterInfo

    pub struct CollectionClusterInfo {
    peer_id : Int64
    shard_count : Int64
    local_shards : Array[LocalShardInfo]
    remote_shards : Array[RemoteShardInfo]
    shard_transfers : Array[ShardTransferInfo]
    }

    Per-collection cluster layout, from GET /collections/{name}/cluster.

    CollectionClusterInfo::from_json

    Parse the collection cluster info result object.

    CollectionConfig

    pub struct CollectionConfig {
    vectors : VectorParams
    named_vectors : Map[String, VectorParams]?
    }

    Collection configuration accepted by PUT /collections/{name}.

    Either a single dense-vector configuration (vectors) or a set of named vector configurations (named_vectors, via CollectionConfig::new_named) can be provided. Qdrant serializes both under the vectors key: a single object for the former, an object keyed by vector name for the latter.

    CollectionConfig::new

    Create a collection with a single dense-vector configuration.

    CollectionConfig::new_named

    fn CollectionConfig::new_named(named_vectors : Map[String, VectorParams]) -> CollectionConfig

    Create a collection with named (multi-) vector configurations, e.g. { "text": VectorParams::new(4, Cosine), "image": VectorParams::new(8, Dot) }. The vectors slot holds a placeholder that is never serialized when named_vectors is set.

    CollectionConfig::to_json

    fn CollectionConfig::to_json(self : CollectionConfig) -> Json

    Convert to the JSON body fragment used by the Qdrant API.

    CollectionInfo

    pub struct CollectionInfo {
    status : String
    points_count : Int?
    vectors : VectorParams?
    }

    Detailed information about a collection, from GET /collections/{name}.

    CollectionInfo::from_json

    fn CollectionInfo::from_json(json : Json) -> CollectionInfo?

    Parse the result object of GET /collections/{name} into a CollectionInfo. points_count and vectors are optional because Qdrant may omit them while a collection is still building.

    CollectionList

    pub struct CollectionList {
    names : Array[String]
    }

    Parsed result of GET /collections: the list of collection names.

    CollectionList::from_json

    fn CollectionList::from_json(json : Json) -> CollectionList?

    CollectionLock

    pub struct CollectionLock {
    write : Bool
    error_message : String?
    }

    Collection lock state, from GET /collections/{name}/lock. When write is true, the collection rejects write operations; the optional error_message is returned to clients on rejected writes.

    CollectionLock::from_json

    fn CollectionLock::from_json(json : Json) -> CollectionLock?

    Parse the lock object: { "write": true, "error_message": "..." }.

    CollectionSummary

    pub struct CollectionSummary {
    name : String
    }

    Minimal parsed view of one collection, from GET /collections.

    CollectionSummary::from_json

    fn CollectionSummary::from_json(json : Json) -> CollectionSummary?

    CollectionUpdate

    pub struct CollectionUpdate {
    vectors : VectorParams?
    named_vectors : Map[String, VectorParams]?
    replication_factor : Int?
    write_consistency_factor : Int?
    }

    Update settings of an existing collection, via PATCH /collections/{name}.

    All fields are optional; unset fields are omitted from the request body. vectors / named_vectors update the vector configuration (changing the size of an existing named vector is not supported by Qdrant), while replication_factor and write_consistency_factor update the shard replication settings.

    CollectionUpdate::new

    fn CollectionUpdate::new(vectors? : VectorParams?, named_vectors? : Map[String, VectorParams]?, replication_factor? : Int?, write_consistency_factor? : Int?) -> CollectionUpdate

    CollectionUpdate::to_json

    fn CollectionUpdate::to_json(self : CollectionUpdate) -> Json

    Convert to the PATCH request body, omitting unset fields.

    Condition

    pub(all) enum Condition {
    MatchValue(String, Json)
    MatchKeyword(String, String)
    MatchValues(String, Array[Json])
    Range(String, Double?, Double?, Double?, Double?)
    IsEmpty(String)
    IsNull(String)
    }

    A single payload filter condition, in the subset of Qdrant's filter DSL that covers the common exact-match, set-membership, range and existence cases. Construct one with the Condition::match_* / Condition::range_* helpers and combine them inside a Filter.

    Condition::is_empty

    fn Condition::is_empty(field : String) -> Condition

    Convenience constructor: payload field has no value.

    Condition::is_null

    fn Condition::is_null(field : String) -> Condition

    Convenience constructor: payload field is explicitly null.

    Condition::match_keyword

    fn Condition::match_keyword(field : String, keyword : String) -> Condition

    Convenience constructor: payload field equals a keyword string.

    Condition::match_value

    fn Condition::match_value(field : String, value : Json) -> Condition

    Convenience constructor: payload field equals a single JSON value.

    Condition::match_values

    fn Condition::match_values(field : String, values : Array[Json]) -> Condition

    Convenience constructor: payload field equals one of the given values.

    Condition::range

    fn Condition::range(field : String, gte? : Double?, lte? : Double?, gt? : Double?, lt? : Double?) -> Condition

    Convenience constructor: numeric range on a payload field. All four bounds are optional; omitted bounds are dropped from the serialized filter.

    Condition::to_json

    fn Condition::to_json(self : Condition) -> Json

    Serialize a Condition to its Qdrant filter JSON fragment.

    Distance

    pub(all) enum Distance {
    Cosine
    Euclid
    Dot
    }

    Distance metric used by a Qdrant vector collection. Wire values follow the Qdrant REST API enum names.

    Distance::from_wire

    fn Distance::from_wire(s : String) -> Distance?

    Parse a Distance from its Qdrant wire string. Returns None for unknown values.

    Distance::to_wire

    fn Distance::to_wire(self : Distance) -> String

    Convert a Distance to its Qdrant wire string.

    FacetHit

    pub struct FacetHit {
    value : Json
    count : Int
    }

    One facet hit from POST /collections/{name}/points/facet: a distinct payload value together with the number of points carrying it.

    FacetHit::from_json

    fn FacetHit::from_json(json : Json) -> FacetHit?

    Parse one facet hit: { "value": "alpha", "count": 3 }.

    FacetResult

    pub struct FacetResult {
    hits : Array[FacetHit]
    exact : Bool
    }

    Result of a facet query: the value-count hits and whether the counts are exact (false when Qdrant used an approximate estimation).

    FacetResult::from_json

    fn FacetResult::from_json(json : Json) -> FacetResult?

    Parse the result object of a facet response: { "hits": [{ "value": ..., "count": n }], "exact": true }.

    Filter

    pub struct Filter {
    must : Array[Condition]
    should : Array[Condition]
    must_not : Array[Condition]
    }

    A Qdrant filter, composed of three conjunctive clause groups.

    Empty clause groups are omitted from the serialized JSON. Use Filter::new() to start, then chain must / should / must_not to add conditions.

    Filter::must

    fn Filter::must(self : Filter, c : Condition) -> Filter

    Append a condition to the must clause group (all must hold).

    Filter::must_not

    fn Filter::must_not(self : Filter, c : Condition) -> Filter

    Append a condition to the must_not clause group (none may hold).

    Filter::new

    fn Filter::new() -> Filter

    Create an empty filter.

    Filter::should

    fn Filter::should(self : Filter, c : Condition) -> Filter

    Append a condition to the should clause group (any may hold).

    Filter::to_json

    fn Filter::to_json(self : Filter) -> Json

    Serialize the filter to Qdrant's filter JSON. Empty clause groups are omitted so the serialized object only contains non-empty groups.

    LocalShardInfo

    pub struct LocalShardInfo {
    shard_id : Int64
    points_count : Int64
    state : String
    }

    A shard replica hosted on the local node.

    LocalShardInfo::from_json

    fn LocalShardInfo::from_json(json : Json) -> LocalShardInfo?

    Parse one local shard entry: { "shard_id": 0, "points_count": 10, "state": "Active" }.

    NamedVector

    pub struct NamedVector {
    name : String
    vector : Array[Double]
    }

    A named vector used as the search input: { "name": "text", "vector": [...] }. Send it as the vector field of a search request to run the query against one specific named vector of the collection.

    NamedVector::new

    fn NamedVector::new(name : String, vector : Array[Double]) -> NamedVector

    NamedVector::to_json

    fn NamedVector::to_json(self : NamedVector) -> Json

    Convert to the Qdrant wire object: { "name": ..., "vector": [...] }.

    PayloadIndexInfo

    pub struct PayloadIndexInfo {
    data_type : String
    field_schema : Json?
    }

    One payload index entry, from the payload_schema of a collection info response.

    PayloadIndexInfo::from_json

    fn PayloadIndexInfo::from_json(json : Json) -> PayloadIndexInfo?

    Parse one payload index entry: { "data_type": "keyword", "field_schema": "keyword", "points": 3 }.

    PeerInfo

    pub struct PeerInfo {
    uri : String?
    last_hb_secs_ago : Int64?
    last_resp_secs_ago : Int64?
    last_update_secs_ago : Int64?
    }

    A remote peer of the cluster, as reported by GET /cluster.

    PeerInfo::from_json

    fn PeerInfo::from_json(json : Json) -> PeerInfo?

    Parse one peer entry: { "uri": "...", "last_hb_secs_ago": 0, ... }.

    PointStruct

    pub struct PointStruct {
    id : Int
    vector : Array[Double]
    named_vectors : Map[String, Array[Double]]?
    payload : Json
    }

    A single point: an id, either a dense vector or a set of named vectors, and an optional JSON payload.

    PointStruct::from_json

    fn PointStruct::from_json(json : Json) -> PointStruct?

    Parse a point object as returned by the point read endpoint: { "id": 1, "vector": [...] | {"name": [...]}, "payload": {...} }. A dense vector array fills vector; a named-vector object fills named_vectors.

    PointStruct::new

    fn PointStruct::new(id : Int, vector : Array[Double], payload : Json) -> PointStruct

    Create a point with a single dense vector.

    PointStruct::new_named

    fn PointStruct::new_named(id : Int, named_vectors : Map[String, Array[Double]], payload : Json) -> PointStruct

    Create a point with named vectors, e.g. { "text": [0.1, 0.2], "image": [0.5, 0.6, 0.7] }.

    PointStruct::to_json

    fn PointStruct::to_json(self : PointStruct) -> Json

    Convert to the point object used by PUT /collections/{name}/points: { "id": 1, "vector": [...] | {"name": [...]}, "payload": {...} }.

    QdrantClient

    pub struct QdrantClient {
    base_url : String
    api_key : String?
    http :
    RequestClient

    }

    Configuration for a QdrantClient.

    QdrantClient::cluster_info

    async fn QdrantClient::cluster_info(self : QdrantClient) -> ClusterInfo

    Read the overall cluster state via GET /cluster: status, local peer id, the peer map and raft consensus info.

    QdrantClient::collection_cluster_info

    async fn QdrantClient::collection_cluster_info(self : QdrantClient, name : String) -> CollectionClusterInfo

    Read the per-collection cluster layout via GET /collections/{name}/cluster: local and remote shard replicas plus in-flight transfers.

    QdrantClient::collection_exists

    async fn QdrantClient::collection_exists(self : QdrantClient, name : String) -> Bool

    Check whether a collection exists via GET /collections/{name}. Returns false when the server answers 404; raises on other errors.

    QdrantClient::collection_info

    async fn QdrantClient::collection_info(self : QdrantClient, name : String) -> CollectionInfo

    Get detailed information about a collection via GET /collections/{name}. Raises when the collection does not exist or the server reports an error.

    QdrantClient::count_points

    async fn QdrantClient::count_points(self : QdrantClient, name : String, filter? : Filter?, exact? : Bool) -> Int

    Count points in a collection via POST /collections/{name}/points/count.

    When exact is false (default) Qdrant answers with an estimate from the index; pass exact=true for an exact count, which is slower on large collections. An optional filter narrows the counted subset.

    QdrantClient::create_alias

    async fn QdrantClient::create_alias(self : QdrantClient, alias_name : String, collection : String) -> Unit

    Create an alias for a collection: POST /collections/aliases with a create_alias action.

    QdrantClient::create_collection

    async fn QdrantClient::create_collection(self : QdrantClient, name : String, config : CollectionConfig) -> Unit

    Create a collection via PUT /collections/{name}.

    QdrantClient::create_payload_index

    async fn QdrantClient::create_payload_index(self : QdrantClient, name : String, field : String, schema : String, wait? : Bool) -> Unit

    Create a payload index on a field via PUT /collections/{name}/index?wait={wait}.

    schema is the field schema, for example "keyword", "integer", "float", "geo", "bool", "text" or "uuid". Creating an index speeds up filtered access to that payload field.

    QdrantClient::create_shard_replica

    async fn QdrantClient::create_shard_replica(self : QdrantClient, name : String, shard_id : Int64, peer_id : Int64) -> Bool

    Create a new shard replica on a peer via POST /collections/{name}/cluster with method create_shard_replica.

    QdrantClient::create_snapshot

    async fn QdrantClient::create_snapshot(self : QdrantClient, name : String, wait? : Bool) -> SnapshotInfo

    Create a snapshot of a collection via POST /collections/{name}/snapshots. Snapshots can be downloaded from the storage and used to restore or migrate a collection.

    QdrantClient::delete_alias

    async fn QdrantClient::delete_alias(self : QdrantClient, alias_name : String) -> Unit

    Delete an alias: POST /collections/aliases with a delete_alias action.

    QdrantClient::delete_collection

    async fn QdrantClient::delete_collection(self : QdrantClient, name : String) -> Unit

    Delete a collection via DELETE /collections/{name}. Raises when the collection does not exist or the server reports an error.

    QdrantClient::delete_payload

    async fn QdrantClient::delete_payload(self : QdrantClient, name : String, ids? : Array[Int]?, filter? : Filter?, wait? : Bool) -> Unit

    Delete the whole payload of the selected points via POST /collections/{name}/points/payload/delete.

    Pass either ids or filter to select the target points. To remove only some keys, use delete_payload_by_keys.

    QdrantClient::delete_payload_by_keys

    async fn QdrantClient::delete_payload_by_keys(self : QdrantClient, name : String, keys : Array[String], ids? : Array[Int]?, filter? : Filter?, wait? : Bool) -> Unit

    Delete only the listed payload keys from the selected points via POST /collections/{name}/points/payload/delete.

    Pass either ids or filter to select the target points.

    QdrantClient::delete_payload_index

    async fn QdrantClient::delete_payload_index(self : QdrantClient, name : String, field : String, wait? : Bool) -> Unit

    Delete a payload index via DELETE /collections/{name}/index/{field}.

    QdrantClient::delete_points

    async fn QdrantClient::delete_points(self : QdrantClient, name : String, ids : Array[Int], wait? : Bool) -> Unit

    Delete points by id via POST /collections/{name}/points/delete. Pass wait=false to return immediately.

    QdrantClient::delete_points_by_filter

    async fn QdrantClient::delete_points_by_filter(self : QdrantClient, name : String, filter : Filter, wait? : Bool) -> Unit

    Delete points selected by a filter via POST /collections/{name}/points/delete.

    This is the bulk-delete variant: every point matching filter is removed in one operation, without listing ids first.

    QdrantClient::delete_shard_replica

    async fn QdrantClient::delete_shard_replica(self : QdrantClient, name : String, shard_id : Int64, peer_id : Int64) -> Bool

    Delete a shard replica from a peer via POST /collections/{name}/cluster with method delete_shard_replica.

    QdrantClient::delete_snapshot

    async fn QdrantClient::delete_snapshot(self : QdrantClient, name : String, snapshot : String, wait? : Bool) -> Unit

    Delete a snapshot via DELETE /collections/{name}/snapshots/{snapshot}.

    QdrantClient::facet_points

    async fn QdrantClient::facet_points(self : QdrantClient, name : String, key : String, limit : Int, filter? : Filter?, exact? : Bool) -> FacetResult

    Count the distinct values of a payload field via POST /collections/{name}/facet.

    key is the payload field to facet on; limit bounds how many distinct values are returned (by descending count). Pass exact=true for exact counts instead of the faster approximate estimation.

    QdrantClient::get_locks

    async fn QdrantClient::get_locks(self : QdrantClient) -> CollectionLock

    Read the global write lock state via GET /locks. Qdrant locks are service-wide (not per-collection); when write is true the service rejects write operations.

    QdrantClient::get_point

    async fn QdrantClient::get_point(self : QdrantClient, name : String, id : Int, with_payload? : Bool, with_vector? : Bool) -> PointStruct?

    Fetch a single point via GET /collections/{name}/points/{id}. Returns None when the point does not exist (404).

    QdrantClient::health

    async fn QdrantClient::health(self : QdrantClient) -> Bool

    Check the server health via GET /healthz. Qdrant answers this endpoint with plain text ("healthz check passed"), so only the HTTP status code is inspected: 200 means healthy.

    QdrantClient::list_aliases

    async fn QdrantClient::list_aliases(self : QdrantClient) -> Array[AliasInfo]

    List all collection aliases via GET /collections/aliases.

    QdrantClient::list_collections

    async fn QdrantClient::list_collections(self : QdrantClient) -> Array[String]

    List all collection names via GET /collections.

    QdrantClient::list_payload_indexes

    async fn QdrantClient::list_payload_indexes(self : QdrantClient, name : String) -> Array[PayloadIndexInfo]

    List the payload indexes of a collection via GET /collections/{name} (the payload_schema field). Qdrant has no dedicated list-indexes endpoint.

    QdrantClient::list_snapshots

    async fn QdrantClient::list_snapshots(self : QdrantClient, name : String) -> Array[SnapshotInfo]

    List the snapshots of a collection via GET /collections/{name}/snapshots.

    QdrantClient::new

    fn QdrantClient::new(base_url : String, api_key? : String?, timeout_ms? : Int) -> QdrantClient

    Create a client for the given base URL.

    Example: QdrantClient::new("http://localhost:6333")

    api_key is optional and, when set, is sent as the api-key header expected by Qdrant's API-key authentication.

    QdrantClient::overwrite_payload

    async fn QdrantClient::overwrite_payload(self : QdrantClient, name : String, payload : Json, ids? : Array[Int]?, filter? : Filter?, wait? : Bool) -> Unit

    Overwrite the payload of the given points via POST /collections/{name}/points/payload.

    Unlike set_payload, the whole payload is replaced by the given object.

    QdrantClient::query_nearest

    async fn QdrantClient::query_nearest(self : QdrantClient, name : String, vector : Array[Double], limit : Int, filter? : Filter?, using_vector? : String?, score_threshold? : Double?, with_payload? : Bool, with_vector? : Bool) -> Array[ScoredPoint]

    Nearest-neighbor query via the query API: find points closest to vector. Equivalent to search_points but routed through /points/query.

    QdrantClient::query_points

    async fn QdrantClient::query_points(self : QdrantClient, name : String, query : Json, limit : Int, filter? : Filter?, using_vector? : String?, score_threshold? : Double?, with_payload? : Bool, with_vector? : Bool) -> Array[ScoredPoint]

    Run a query against the Qdrant query API via POST /collections/{name}/points/query.

    query is the raw query JSON, for example { "nearest": [0.1, 0.2, 0.3, 0.4] } or { "recommend": { "positive": [[...]], "negative": [[...]] } }. Prefer the query_nearest / query_recommend helpers for common cases.

    QdrantClient::query_recommend

    async fn QdrantClient::query_recommend(self : QdrantClient, name : String, positive : Array[Json], negative? : Array[Json]?, limit : Int, filter? : Filter?, using_vector? : String?, score_threshold? : Double?, with_payload? : Bool, with_vector? : Bool) -> Array[ScoredPoint]

    Recommendation query via the query API: find points similar to the positive inputs and dissimilar to the negative ones.

    Each element of positive / negative is either a dense vector (Json::array([...])) or a point id (Json::number(id)).

    QdrantClient::replicate_shard

    async fn QdrantClient::replicate_shard(self : QdrantClient, name : String, shard_id : Int64, from_peer_id : Int64, to_peer_id : Int64) -> Bool

    Replicate a shard to another peer via POST /collections/{name}/cluster with method replicate_shard.

    QdrantClient::retrieve_points

    async fn QdrantClient::retrieve_points(self : QdrantClient, name : String, ids : Array[Int], with_payload? : Bool, with_vector? : Bool) -> Array[PointStruct]

    Fetch several points at once by id via POST /collections/{name}/points.

    Points that do not exist are simply omitted from the returned list; check the length against the requested ids to detect missing ones.

    QdrantClient::scroll_points

    async fn QdrantClient::scroll_points(self : QdrantClient, name : String, limit : Int, filter? : Filter?, offset? : Int?, with_payload? : Bool, with_vector? : Bool) -> ScrollResult

    Scroll through all points of a collection via POST /collections/{name}/points/scroll.

    Returns one page of points together with next_page_offset, which is Some(offset) when more pages remain and None on the last page. Pass it back as offset to fetch the following page.

    QdrantClient::search_points

    async fn QdrantClient::search_points(self : QdrantClient, name : String, vector : Array[Double], limit : Int, filter? : Json?, with_payload? : Bool, with_vector? : Bool, score_threshold? : Double?, offset? : Int?, using_vector? : String?, search_params? : SearchParams?) -> Array[ScoredPoint]

    Search the most similar points via POST /collections/{name}/points/search.

    limit bounds how many hits are returned. filter is an optional Qdrant filter JSON object, for example { "must": [{ "key": "tag", "match": { "value": "alpha" } }] }.

    Advanced options: score_threshold keeps only hits above the score, offset paginates search results, using_vector selects which named vector to query against, and search_params carries search-time tuning (hnsw_ef, exact).

    QdrantClient::search_points_batch

    async fn QdrantClient::search_points_batch(self : QdrantClient, name : String, searches : Array[Json]) -> Array[Array[ScoredPoint]]

    Run several searches in one round trip via POST /collections/{name}/points/search/batch.

    Each element is a search request JSON object, for example { "vector": [...], "limit": 5, "with_payload": true }; the returned array has one entry (itself an array of hits) per request.

    QdrantClient::search_points_groups

    async fn QdrantClient::search_points_groups(self : QdrantClient, name : String, vector : Array[Double], limit : Int, group_by : String, group_size : Int, filter? : Json?, with_payload? : Bool, with_vector? : Bool, score_threshold? : Double?, using_vector? : String?, search_params? : SearchParams?) -> Array[ScoredPointGroup]

    Grouped search via POST /collections/{name}/points/search/groups.

    Points are grouped by the payload field group_by; limit bounds the hits returned per group and group_size bounds the number of groups. The result is one entry per group with its top hits.

    QdrantClient::search_points_named

    async fn QdrantClient::search_points_named(self : QdrantClient, name : String, named_vector : NamedVector, limit : Int, filter? : Json?, with_payload? : Bool, with_vector? : Bool, score_threshold? : Double?, offset? : Int?, search_params? : SearchParams?) -> Array[ScoredPoint]

    Search with a named vector as input: the query vector is matched against the named vector with the given name (Qdrant supports several vectors per point). using is implied by the name carried in named_vector.

    QdrantClient::search_points_with_filter

    async fn QdrantClient::search_points_with_filter(self : QdrantClient, name : String, vector : Array[Double], limit : Int, filter : Filter, with_payload? : Bool, with_vector? : Bool, score_threshold? : Double?, offset? : Int?, using_vector? : String?, search_params? : SearchParams?) -> Array[ScoredPoint]

    Search with a type-safe Filter built from Condition helpers. This is the preferred way to build payload filters; the raw-Json search_points variant remains for advanced cases.

    QdrantClient::search_with_filter

    async fn QdrantClient::search_with_filter(self : QdrantClient, name : String, vector : Array[Double], limit : Int, filter : Filter, with_payload? : Bool, with_vector? : Bool) -> Array[ScoredPoint]

    Trait-facing alias of search_points_with_filter: the trait method is named search_with_filter, so this method exists under that name and forwards to the full-featured search entry point. Defining it as a regular method (rather than inside the impl block) keeps the trait implementation free of deprecated implicit method promotion.

    QdrantClient::service_info

    async fn QdrantClient::service_info(self : QdrantClient) -> ServiceInfo

    Read server info via GET /service: the Qdrant version and commit hash.

    QdrantClient::set_locks

    async fn QdrantClient::set_locks(self : QdrantClient, write : Bool, error_message? : String?) -> Unit

    Set the global write lock state via POST /locks.

    When write is true the service rejects write operations; provide an optional error_message returned to clients on rejected writes.

    QdrantClient::set_payload

    async fn QdrantClient::set_payload(self : QdrantClient, name : String, payload : Json, ids? : Array[Int]?, filter? : Filter?, wait? : Bool) -> Unit

    Set (merge) a payload on the given points via PUT /collections/{name}/points/payload.

    Pass either ids or filter to select the target points. The payload fields are merged into each point's existing payload.

    QdrantClient::update_collection

    async fn QdrantClient::update_collection(self : QdrantClient, name : String, update : CollectionUpdate) -> Unit

    Update collection settings via PATCH /collections/{name}.

    See CollectionUpdate for which settings can be changed.

    QdrantClient::upsert_points

    async fn QdrantClient::upsert_points(self : QdrantClient, name : String, points : Array[PointStruct], wait? : Bool) -> Unit

    Upsert points into a collection via PUT /collections/{name}/points. Pass wait=false to return immediately; the operation may still be propagating on the server.

    QdrantClient::upsert_points_batch

    async fn QdrantClient::upsert_points_batch(self : QdrantClient, name : String, points : Array[PointStruct], wait? : Bool) -> Unit

    Upsert points through the batch endpoint via PUT /collections/{name}/points/batch. The batch format packs ids, vectors and payloads into parallel arrays, which Qdrant applies as a single request.

    RaftInfo

    pub struct RaftInfo {
    term : Int64?
    commit : Int64?
    pending_operations : Int64?
    leader : Int64?
    role : String?
    is_voter : Bool?
    }

    Raft consensus state of the cluster.

    RaftInfo::from_json

    fn RaftInfo::from_json(json : Json) -> RaftInfo?

    Parse the raft_info object of a cluster response.

    RemoteShardInfo

    pub struct RemoteShardInfo {
    shard_id : Int64
    peer_id : Int64
    state : String
    }

    A shard replica hosted on a remote peer.

    RemoteShardInfo::from_json

    fn RemoteShardInfo::from_json(json : Json) -> RemoteShardInfo?

    Parse one remote shard entry: { "shard_id": 0, "peer_id": 1, "state": "Active" }.

    ScoredPoint

    pub struct ScoredPoint {
    id : Int
    score : Double
    payload : Json?
    }

    One hit returned by the search endpoint: a point id, its similarity score, and the payload attached to the point (when requested).

    ScoredPoint::from_json

    fn ScoredPoint::from_json(json : Json) -> ScoredPoint?

    Parse a search hit object: { "id": 1, "score": 0.99, "payload": {...} }.

    ScoredPointGroup

    pub struct ScoredPointGroup {
    id : Json
    hits : Array[ScoredPoint]
    }

    One group returned by the grouped search endpoint: the group id (the payload value points were grouped by) and the top hits within the group.

    ScoredPointGroup::from_json

    fn ScoredPointGroup::from_json(json : Json) -> ScoredPointGroup?

    Parse one search group: { "hits": [...], "id": "alpha" }.

    ScrollResult

    pub struct ScrollResult {
    points : Array[PointStruct]
    next_page_offset : Int?
    }

    Result of POST /collections/{name}/points/scroll: the points on the current page, and the next page offset when more pages remain.

    ScrollResult::from_json

    fn ScrollResult::from_json(json : Json) -> ScrollResult?

    Parse the result object of a scroll response.

    SearchParams

    pub struct SearchParams {
    hnsw_ef : Int?
    exact : Bool?
    }

    Search-time parameters passed in the params field of a search request. Both fields are optional; only the set ones are serialized.

    SearchParams::new

    fn SearchParams::new(hnsw_ef? : Int?, exact? : Bool?) -> SearchParams

    SearchParams::to_json

    fn SearchParams::to_json(self : SearchParams) -> Json

    Convert to the Qdrant wire object, omitting unset fields.

    ServiceInfo

    pub struct ServiceInfo {
    version : String?
    commit : String?
    }

    Server info from GET /service: the running Qdrant version and build metadata when present.

    ServiceInfo::from_json

    fn ServiceInfo::from_json(json : Json) -> ServiceInfo?

    Parse the service info object.

    ShardTransferInfo

    pub struct ShardTransferInfo {
    shard_id : Int64
    from : Int64
    to : Int64
    method_name : String?
    }

    An in-flight shard transfer between two peers.

    ShardTransferInfo::from_json

    fn ShardTransferInfo::from_json(json : Json) -> ShardTransferInfo?

    Parse one shard transfer entry.

    SnapshotInfo

    pub struct SnapshotInfo {
    name : String
    creation_time : String?
    size : Int?
    }

    One snapshot entry, from GET /collections/{name}/snapshots or GET /snapshots.

    SnapshotInfo::from_json

    fn SnapshotInfo::from_json(json : Json) -> SnapshotInfo?

    Parse one snapshot entry: { "name": "snap-1", "creation_time": "...", "size": 123 }.

    VectorParams

    pub struct VectorParams {
    size : Int
    distance : Distance
    }

    Vector configuration for a collection, as accepted by PUT /collections/{name}.

    VectorParams::from_json

    fn VectorParams::from_json(json : Json) -> VectorParams?

    Parse VectorParams from the config fragment returned by GET /collections/{name}.

    VectorParams::new

    fn VectorParams::new(size : Int, distance : Distance) -> VectorParams

    VectorParams::to_json

    fn VectorParams::to_json(self : VectorParams) -> Json

    Convert to the JSON body fragment used by the Qdrant API: { "size": 4, "distance": "Cosine" }.

    collection_cluster_op_body

    fn collection_cluster_op_body(op : String, shard_id : Int64, peer_id? : Int64?, from_peer_id? : Int64?, to_peer_id? : Int64?) -> Json

    Build the request body for a collection cluster operation (POST /collections/{name}/cluster). op is one of the Qdrant operation names: replicate_shard, create_shard_replica, delete_shard_replica, abort_transfer, ...

    count_request_body

    fn count_request_body(filter : Filter?, exact : Bool) -> Json

    Build the request body for POST /collections/{name}/points/count.

    int64_of_json

    fn int64_of_json(json : Json) -> Int64?

    Read an integer from a JSON number, using the original textual representation when available so u64 values survive without loss.

    int64_to_json

    fn int64_to_json(v : Int64) -> Json

    Serialize an Int64 as a JSON number. Values within the exact-double range (|v| < 2^53) round-trip losslessly; peer ids from Qdrant are u64 but in practice stay well below that bound.

    join_url

    fn join_url(base : String, path : String) -> String

    Join a path fragment onto the base URL, keeping a single slash between them.

    parse_aliases

    fn parse_aliases(json : Json) -> Array[AliasInfo]?

    Parse the result.aliases array of GET /collections/aliases.

    parse_count_result

    fn parse_count_result(json : Json) -> Int?

    Parse the result object of a count response: { "count": 42 }. Returns None when the shape does not match.

    parse_int64

    fn parse_int64(s : String) -> Int64?

    Parse a base-10 integer string into an Int64, tolerating a leading '-'. Used to decode large JSON numbers (peer ids, shard ids) from their original textual representation without precision loss.

    parse_payload_indexes

    fn parse_payload_indexes(json : Json) -> Array[PayloadIndexInfo]?

    Parse the payload indexes of a collection. Qdrant has no dedicated "list indexes" endpoint; the schema is returned as payload_schema inside GET /collections/{name}. Each key is a field name and each value is an index descriptor like { "data_type": "keyword", "points": 3, ... }.

    parse_query_result

    fn parse_query_result(json : Json) -> Array[ScoredPoint]?

    Parse the result of a query response into scored points.

    The query API returns { "result": { "points": [...], "next_page_offset": ... } } (an object), unlike the search API which returns { "result": [...] }. Both shapes are accepted here.

    parse_retrieve_result

    fn parse_retrieve_result(json : Json) -> Array[PointStruct]?

    Parse the result array of a retrieve response into points. Returns None when the response does not match the expected shape.

    parse_scored_array

    fn parse_scored_array(arr : Array[Json]) -> Array[ScoredPoint]?

    Parse an array of scored point objects into ScoredPoint values. Returns None when any element does not match the expected shape.

    parse_search_groups

    fn parse_search_groups(json : Json) -> Array[ScoredPointGroup]?

    Parse the result.groups array of a grouped search response.

    parse_search_result

    fn parse_search_result(json : Json) -> Array[ScoredPoint]?

    Parse the result array of a search response into scored points. Returns None when the response does not match the expected shape.

    parse_snapshots

    fn parse_snapshots(json : Json) -> Array[SnapshotInfo]?

    Parse the result array of a snapshots response.

    scroll_request_body

    fn scroll_request_body(limit : Int, filter : Filter?, offset : Int?, with_payload : Bool, with_vector : Bool) -> Json

    Build the request body for POST /collections/{name}/points/scroll.

    vector_to_json

    fn vector_to_json(vector : Array[Double]) -> Json

    Convert a dense vector to its JSON array representation. Shared by point serialization, batch upsert and search.