Code Monkey home page Code Monkey logo

rust-client's Introduction

Qdrant Rust client

The Qdrant - High-Performance Vector Search at Scale - client for Rust.

Crates.io docs.rs Apache 2.0 licensed

Documentation:

Installation

cargo add qdrant-client

Package is available in crates.io

Examples

A list of example snippets can be found here

More examples can be found in the examples folder

Dependencies

The client uses gRPC via the Tonic library.

To change anything in the protocol buffer definitions, you need the protoc Protocol Buffers compiler, along with Protocol Buffers resource files.

Refer to the Tonic installation guide for more details.

Usage

Run Qdrant with enabled gRPC interface:

# With env variable
docker run -p 6333:6333 -p 6334:6334 \
    -e QDRANT__SERVICE__GRPC_PORT="6334" \
    qdrant/qdrant

Or by updating the configuration file:

service:
  grpc_port: 6334

More info about gRPC in documentation.

Making requests

Add necessary dependencies:

cargo add qdrant-client anyhow tonic tokio serde-json --features tokio/rt-multi-thread

Add search example from examples/search.rs to your src/main.rs:

use qdrant_client::qdrant::{
    Condition, CreateCollectionBuilder, Distance, Filter, PointStruct, ScalarQuantizationBuilder,
    SearchParamsBuilder, SearchPointsBuilder, UpsertPointsBuilder, VectorParamsBuilder,
};
use qdrant_client::{Payload, Qdrant, QdrantError};

#[tokio::main]
async fn main() -> Result<(), QdrantError> {
    // Example of top level client
    // You may also use tonic-generated client from `src/qdrant.rs`
    let client = Qdrant::from_url("http://localhost:6334").build()?;

    let collections_list = client.list_collections().await?;
    dbg!(collections_list);
    // collections_list = {
    //   "collections": [
    //     {
    //       "name": "test"
    //     }
    //   ]
    // }

    let collection_name = "test";
    client.delete_collection(collection_name).await?;

    client
        .create_collection(
            CreateCollectionBuilder::new(collection_name)
                .vectors_config(VectorParamsBuilder::new(10, Distance::Cosine))
                .quantization_config(ScalarQuantizationBuilder::default()),
        )
        .await?;

    let collection_info = client.collection_info(collection_name).await?;
    dbg!(collection_info);

    let payload: Payload = serde_json::json!(
        {
            "foo": "Bar",
            "bar": 12,
            "baz": {
                "qux": "quux"
            }
        }
    )
    .try_into()
    .unwrap();

    let points = vec![PointStruct::new(0, vec![12.; 10], payload)];
    client
        .upsert_points(UpsertPointsBuilder::new(collection_name, points))
        .await?;

    let search_result = client
        .search_points(
            SearchPointsBuilder::new(collection_name, [11.; 10], 10)
                .filter(Filter::all([Condition::matches("bar", 12)]))
                .with_payload(true)
                .params(SearchParamsBuilder::default().exact(true)),
        )
        .await?;
    dbg!(&search_result);
    // search_result = [
    //   {
    //     "id": 0,
    //     "version": 0,
    //     "score": 1.0000001,
    //     "payload": {
    //       "bar": 12,
    //       "baz": {
    //         "qux": "quux"
    //       },
    //       "foo": "Bar"
    //     }
    //   }
    // ]

    let found_point = search_result.result.into_iter().next().unwrap();
    let mut payload = found_point.payload;
    let baz_payload = payload.remove("baz").unwrap().into_json();
    println!("baz: {}", baz_payload);
    // baz: {"qux":"quux"}

    Ok(())
}

Or run the example from this project directly:

cargo run --example search

Qdrant Cloud

Qdrant Cloud is a managed service for Qdrant.

The client needs to be configured properly to access the service.

  • make sure to use the correct port (6334)
  • make sure to pass your API KEY
use qdrant_client::Qdrant;

let client = Qdrant::from_url("http://xxxxxxxxxx.eu-central.aws.cloud.qdrant.io:6334")
    // Use an environment variable for the API KEY for example
    .api_key(std::env::var("QDRANT_API_KEY"))
    .build()?;

rust-client's People

Contributors

agourlay avatar ava57r avatar ccqpein avatar codabrink avatar coszio avatar davidmyriel avatar edgera avatar generall avatar ivanpleshkov avatar jojiiofficial avatar llogiq avatar nigecat avatar nkbelov avatar no-materials avatar paulotten avatar timvisee avatar xmakro avatar xzfc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-client's Issues

feature request: add seperate function for full-text-search for filters

We are attempting to use qdrant's full text filters in order to be able to move our filtering logic to solely qdrant, however we were facing issues with the fact that qdrant's rust client only support full text matching when there is a space added to the end.

We want to be able to use qdrant's full text and substring filtering as a replacement for the LIKE queries that we perform in pg as of rn, however, in certain cases where we have multi word filters or single word filters, the logic would behave unpredictably.

Here is a link the the gist that contains our filtering logic: https://gist.github.com/skeptrunedev/3ede217aa78d6462c5c52c63d0318764.

The easiest solution to this issue is probably adding a separate full text match function like python does.

Thank you so much for a first class rust client and an amazing SVD!!

Issues connecting to Qdrant Cloud using client.

Hey,

I'm encountering errors while trying to use the list_collections method with the Qdrant Rust client. This error seems to be specific to the client as directly accessing the endpoint doesn't produce any issues.

Here are the specifics:

  1. When I try to use port 6333, I receive the following error:
Err value: status: Unknown, message: "grpc-status header missing, mapped from HTTP status code 464", details: [], 
metadata: MetadataMap { headers: {"server": "awselb/2.0", "date": "Tue, 25 Jul 2023 14:08:49 GMT", "content-length": "0"} }
  1. When I switch to port 6334, I get a different error message:
Err value: status: Internal, message: "protocol error: received message with invalid 
compression flag: 52 (valid flags are 0 and 1)  while receiving response with status: 404 Not Found", details: [], 
metadata: MetadataMap { headers: {"server": "awselb/2.0", "date": "Tue, 25 Jul 2023 15:21:54 GMT", 
"content-type": "text/plain; charset=utf-8", "content-length": "19", "x-content-type-options": "nosniff"} }

I'm following the search example but using Qdrant Cloud

Any insights or suggestions to address this would be greatly appreciated.

Clippy on CI

Fix all Clippy issues and setup CI to validate it.

Grpc-status header missing when using qdrant-cloud:

Set up client and a collection create request as per the pod readme:

    let client = QdrantClient::from_url(QDRANT_DB_URL)
    // using an env variable for the API KEY for example
    .with_api_key(API_KEY)
    .build()?;

Creating a collection:

    client
        .create_collection(&CreateCollection { collection_name: collection_name.into(), 
             vectors_config: Some(VectorsConfig {
                config: Some (Config::Params(VectorParams {
                    size: 128,
                    distance: Distance::Euclid.into(),
                    ..Default::default()
                })),
             }),
             ..Default::default()
             }).await?;

The create_collection command fails with this error: Error: status: Unknown, message: "grpc-status header missing, mapped from HTTP status code 464", details: [], metadata: MetadataMap { headers: {"server": "awselb/2.0", "date": "Thu, 21 Sep 2023 23:57:02 GMT", "content-length": "0"} }

Semver breakage when updating qdrant-client from 1.3 to 1.7

E.g. in FieldCondition, a new field geo_polygon was added and a new parameter was added to upsert_points_blocking.
I realize that this library's code is generated from the protobuf files which may complicate things. Still, what is the version compatibility policy for this crate? If possible, adhering to semver would be nice as all the Rust tooling assumes semver compatibility is kept (e.g. cargo upgrade + cargo update will update from 1.3 to 1.7 in Cargo.lock and break the build). Hence, I assume the version always needs to be pinned as of now. Thanks!

Range type should have the ability to hold both f64 and i64 fields

Hi, according to the docs, it is possible to use range filtering on both float and integer payloads but the Range client type can only hold f64 optional fields, i.e.:

rust-client/src/qdrant.rs

Lines 2931 to 2940 in cd7ee0f

pub struct Range {
#[prost(double, optional, tag = "1")]
pub lt: ::core::option::Option<f64>,
#[prost(double, optional, tag = "2")]
pub gt: ::core::option::Option<f64>,
#[prost(double, optional, tag = "3")]
pub gte: ::core::option::Option<f64>,
#[prost(double, optional, tag = "4")]
pub lte: ::core::option::Option<f64>,
}

Docs: Mention that the Rust client explicitly needs port 6334 in URL for Qdrant cloud

The cluster manager allows developers to copy a cluster's URL into the clipboard. That is convenient. If this URL is used with the Rust client, it does not work. It results in a 464 (incompatible protocol) error. As a developer, you have to add :6334 to the URL to make it work. It would be helpful to have a hint in the cluster manager and/or the Rust client docs that this is important.

Error type checking

Hi.
I see that you library uses anyhow lib for error handling.
Question.
Client has recoverable errors or all types of errors critical?

I am trying to check error when

  • collection exists
  • timeout expired

I get anyhow::Error and can not split these cases.

Enhancements for the `ChannelPool`

Background:

ChannelPool is a struct for managing gRPC client connections, providing basic connection pooling functionality. While it already offers some useful features, there are potential improvements and extensions that could further enhance performance, stability, and maintainability.

Proposed Features:

  • Maximum Connection Limit: To prevent creating too many simultaneous connections, consider adding a maximum connection limit to the ChannelPool struct. Concurrent connection creation can be controlled using a Semaphore or other concurrency control structures.

  • Connection Expiration: Add an expiration time for each connection in the ChannelPool. Connections exceeding this duration would be automatically closed, ensuring connections don't remain open indefinitely.

I chose to implement these two features because they can significantly improve performance and reduce resource usage. Additionally, these features lay the groundwork for future improvements.
There are also any other features about ChannelPool, for example :

  • Smarter Connection Recycling Strategy: The current implementation simply discards connections when they encounter errors. Implement a smarter recycling strategy, such as deciding when to close connections based on their usage frequency or idle time.

  • Connection Health Checks: Perform periodic health checks on connections to ensure that the connections in the pool are still functional. If unhealthy connections are discovered, remove them from the pool and create new connections as needed.

  • Connection Load Balancing: If connecting to a service with multiple backend instances, consider implementing connection load balancing. Choose between round-robin, least connections, or other load balancing strategies based on connection usage.

  • Detailed Error Handling and Logging: For easier debugging and troubleshooting, consider adding more detailed error handling and logging within the code.

  • Generics: The current implementation of the with_channel method requires a function returning a Result<T, Status>. Consider using a generic error type to make it more adaptable to different error handling requirements.

Consider using cargo-semver-checks

There was a semver breakage mentioned in #87 and I was sceptical that a builder pattern would actually solve the issue because it doesn't stop you changing APIs in a semver incompatible manner at all. So as I saw qdrant-client had been updated again since I last checked I ran a cargo-semver-checks on it and it failed. Between 1.10.1 and 1.10.2 there was a "technically" breaking change.

cargo semver-checks --baseline-version 1.10.1
     Parsing qdrant-client v1.10.2 (current)
      Parsed [  28.700s] (current)
     Parsing qdrant-client v1.10.1 (baseline)
      Parsed [  37.051s] (baseline)
    Checking qdrant-client v1.10.1 -> v1.10.2 (patch change)
     Checked [   0.193s] 76 checks: 75 pass, 1 fail, 0 warn, 0 skip

--- failure module_missing: pub module removed or renamed ---

Description:
A publicly-visible module cannot be imported by its prior path. A `pub use` may have been removed, or the module may have been renamed, removed, or made non-public.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.33.0/src/lints/module_missing.ron

Failed in:
  mod qdrant_client::qdrant::payloads, previously in file /home/daniel/.cargo/registry/src/index.crates.io-6f17d22bba15001f/qdrant-client-1.10.1/src/qdrant_client/builders/payloads.rs:1

     Summary semver requires new major version: 1 major and 0 minor checks failed
    Finished [  66.212s] qdrant-client

So as it didn't list any items in the module it must be a public module with no public items was removed so the only code it can break is code doing: use qdrant_client::qdrant::payloads as payloads; This isn't a big breakage as a result and the lint is likely to become a warning instead of error lint in future. But I hope it goes some way to demonstrate the usefulness of cargo-semver checks.

We can also look at the 1.9.0 -> 1.10.2 change and see 3 major breakages:

cargo semver-checks --baseline-version 1.9.0
     Parsing qdrant-client v1.10.2 (current)
      Parsed [   4.369s] (current)
     Parsing qdrant-client v1.9.0 (baseline)
      Parsed [  36.069s] (baseline)
    Checking qdrant-client v1.9.0 -> v1.10.2 (minor change)
     Checked [   0.126s] 70 checks: 67 pass, 3 fail, 0 warn, 6 skip

--- failure constructible_struct_adds_field: externally-constructible struct adds field ---

Description:
A pub struct constructible with a struct literal has a new pub field. Existing struct literals must be updated to include the new field.
        ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.33.0/src/lints/constructible_struct_adds_field.ron

Failed in:
  field ScoredPoint.order_value in /home/daniel/rust/rust-client/src/qdrant.rs:4943
  field SparseVectorParams.modifier in /home/daniel/rust/rust-client/src/qdrant.rs:137
  field SparseIndexConfig.datatype in /home/daniel/rust/rust-client/src/qdrant.rs:287
  field VectorParams.multivector_config in /home/daniel/rust/rust-client/src/qdrant.rs:44
  field ShardTransferInfo.to_shard_id in /home/daniel/rust/rust-client/src/qdrant.rs:974
  field MoveShard.to_shard_id in /home/daniel/rust/rust-client/src/qdrant.rs:1017
  field Vector.vectors_count in /home/daniel/rust/rust-client/src/qdrant.rs:3079
  field RetrievedPoint.order_value in /home/daniel/rust/rust-client/src/qdrant.rs:5079
  field AbortShardTransfer.to_shard_id in /home/daniel/rust/rust-client/src/qdrant.rs:1069
  field RestartTransfer.to_shard_id in /home/daniel/rust/rust-client/src/qdrant.rs:1084

--- failure enum_variant_added: enum variant added on exhaustive enum ---

Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.33.0/src/lints/enum_variant_added.ron

Failed in:
  variant ShardTransferMethod:ReshardingStreamRecords in /home/daniel/rust/rust-client/src/qdrant.rs:1635
  variant Datatype:Float16 in /home/daniel/rust/rust-client/src/qdrant.rs:1255
  variant ReplicaState:Resharding in /home/daniel/rust/rust-client/src/qdrant.rs:1591

--- failure module_missing: pub module removed or renamed ---

Description:
A publicly-visible module cannot be imported by its prior path. A `pub use` may have been removed, or the module may have been renamed, removed, or made non-public.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.33.0/src/lints/module_missing.ron

Failed in:
  mod qdrant_client::filters, previously in file /home/daniel/.cargo/registry/src/index.crates.io-6f17d22bba15001f/qdrant-client-1.9.0/src/filters.rs:1

     Summary semver requires new major version: 3 major and 0 minor checks failed
    Finished [  40.723s] qdrant-client

Bad request: Empty update request when points.len() < chunk_size missing points bug

    pub async fn upsert_points_chunked(
        &self,
        request: impl Into<UpsertPoints>,
        chunk_size: usize,
    ) -> QdrantResult<PointsOperationResponse> {
        let mut request = request.into();
        let points = std::mem::take(&mut request.points);

        if points.len() < chunk_size {
            return self.upsert_points(request).await;
        }

        let request = &request;
        let points = &points;

        self.with_points_client(|mut points_api| async move {
            let mut resp = PointsOperationResponse {
                result: None,
                time: 0.0,
            };

            for chunk in points.clone().chunks(chunk_size) {
                let mut chunked_request = request.clone();
                chunked_request.points = chunk.to_vec();

                let PointsOperationResponse { result, time } =
                    points_api.upsert(chunked_request).await?.into_inner();

                resp.result = result;
                resp.time += time;
            }

            Ok(resp)
        })
        .await
    }

Docs: Provided sample code does not work, outdated?

The provided sample code in the readme file does not work.

Reproduction

  • Create a new Rust app with cargo new
  • Add all the necessary dependencies (e.g. qdrant-client, tokio, etc.)
  • Copy the provided sample code from Qdrant Rust Client readme file
  • Try to compile

Result

Does not compile.

Expected result

Compiles successfully.

Transport Error when connecting to Qdrant Cloud

I have a cluster set up on Qdrant Cloud. When I click "code sample" in the UI and select rust, it gives me the following code:

use qdrant_client::Qdrant;

#[tokio::main]
async fn main() {
  let client = Qdrant::from_url("https://[cluster id].us-east4-0.gcp.cloud.qdrant.io:6334")
      .api_key("<your-token>")
      .build()
      .unwrap();
      
  let collections_list = client.list_collections().await;
  let _ = dbg!(collections_list);
}

When I run this exact code (substituting in the cluster id and my api key), I get the following output:

[src/main.rs:31:13] collections_list = Err(
    ResponseError {
        status: Status {
            code: Internal,
            message: "Failed to connect to https://[cluster id].us-east4-0.gcp.cloud.qdrant.io:6334/: transport error",
            source: None,
        },
    },
)

I have run this code both from my local machine (m3 max macbook pro) and from a remote ubuntu machine on GCP.

I have also run the following curl command from my local machine:

curl -X GET "${QDRANT_CLUSTER_URL}:6333" -H "api-key: ${QDRANT_API_KEY}"

And received a valid response. This leads me to believe that the issue is either grpc related or rust client related.

I've looked at some of the previous (closed) issues that dealt with connection issues, and it looks like they were mostly url typos. I've tried a number of variations to make sure that isn't the case here for me.

I am using the 1.10.2 version of the client, and my qdrant cloud cluster is running v1.10.1

Bug: `update_collection` only accepts `optimizer_config` parameter

Currently, update_collection() only accepts the optimizers_config parameter.

This is a problem as we've added new parameters in recent Qdrant versions. For example, updating vector parameters is currently impossible.

We should patch this to support all parameters as described here.

To prevent breaking changes in the current minor version we might have to add a second update_collection function which supports all arguments. We can add the new arguments to the current function in 1.7.

cc @Anush008

Blocking API version

Clients don't have to be async, it's more the necessity for the server-side components. But this library forces a client to run inside an async runtime introducing unnecessary complexity for many cases.

Failed to connect

Below is the error message I received. I am coding an actix-web service and one part of it is to store vectors into Qdrant. But the Rust Qdrant does not connect to the database. The curl was okay on both 6333 and 6334.
[2024-07-08T10:50:25Z ERROR rust_backend::utilities::vector_database_interfaces] ResponseError { status: Status { code: Internal, message: "Failed to connect to 0.0.0.0:6334: transport error", source: None } }

Below is a sample code that generates the error:

use qdrant_client::qdrant::{vectors_config::Config, VectorParams, VectorsConfig, CreateCollection, Distance};


#[tokio::main]
async fn main() {
    // initialize a qdrant client
    let client = qdrant_client::Qdrant::from_url(
        "192.168.0.101:6334"
    )
        .build()
        .expect("Cannot initiate the client");

    // create a collection for storing documents
    match client.create_collection(
        CreateCollection {
            collection_name: "test".to_string(),
            vectors_config: Some(
                VectorsConfig {
                    config: Some(
                        Config::Params(
                            VectorParams {
                                size: 1024,
                                distance: Distance::Cosine.into(),
                                ..Default::default()
                            }
                        )
                    ),
                }
            ),
            ..Default::default()
        }
    ).await {
        Ok(result) => println!("{:?}", result), 
        Err(error) => {
            println!("{:?}", error);
        }
    };
}

I am not sure, maybe something went wrong on my end?

Transport Error

I have a Tauri (Rust) desktop app that uses a local qdrant for vector storage. Even after waiting for the gRPC channel message and a health check from the server I still get the following error when later in the code I'm trying to use my generated rust client object:

Err(status: Internal, message: "Failed to connect to http://localhost:6334/: transport error", details: [], metadata: MetadataMap { headers: {} })

Does anyone have any suggestions for what the issue might be? This only occurs on a subset of the machines I'm testing with.

Takes longer time than `Python` client on get_points

OS: Windows11

rust(release ~308ms):

use anyhow::Result;

use qdrant_client::prelude::*;
#[actix_web::main]
async fn main() -> Result<()> {
    let client = QdrantClientBuilder::default().build()?;
    let collection_name = "test_collection";
    let t = std::time::Instant::now();
    client
        .get_points(
            collection_name,
            None,
            &[
                "211b0f43-1b8d-4d12-9dd3-62aa0f07a8c6".to_owned().into(),
                "bdd8a0a7-8f39-4b3e-9a92-7a8e2c6f0a4d".to_owned().into(),
                "9cda8e6d-6e0f-4e33-8a6b-2e3b13d6a2e2".to_owned().into(),
                "e9e6e4e9-3b69-4edf-9a5c-a9e8b4df8a66".to_owned().into(),
                "4f80c7a1-4f7b-4c79-94a4-8e20c3f6a1e3".to_owned().into(),
                "17b73663-3a8c-4e5d-9a7d-ec7bba2a8bcf".to_owned().into(),
            ],
            Some(false),
            Some(true),
            None,
        )
        .await?;
    println!("\n{:?}", t.elapsed());
    Ok(())
}

python(~270ms):

from qdrant_client import QdrantClient

client = QdrantClient(prefer_grpc=True)
t = time.time()
client.retrieve(
    "test_collection",
    [
        "211b0f43-1b8d-4d12-9dd3-62aa0f07a8c6",
        "bdd8a0a7-8f39-4b3e-9a92-7a8e2c6f0a4d",
        "9cda8e6d-6e0f-4e33-8a6b-2e3b13d6a2e2",
        "e9e6e4e9-3b69-4edf-9a5c-a9e8b4df8a66",
        "4f80c7a1-4f7b-4c79-94a4-8e20c3f6a1e3",
        "17b73663-3a8c-4e5d-9a7d-ec7bba2a8bcf",
    ],
)
print(time.time() - t)

I know it's minor but I wonder is it related with Tonic or client itself ?

Backward compatibility

Hello
I have some qdrant instances
first of them v1.6.1
second of them v1.5.1

Can I use this client v1.6.1 with qdrant v1.5.1?

example needs " on_disk:None" | else no compile

eg:

vectors_config: Some(VectorsConfig { config: Some(Config::Params(VectorParams { size: 10, distance: Distance::Cosine.into(), hnsw_config: None, quantization_config: None, ****on_disk:None**** })),

Vectors only support `f32` - should also support `f64`

I noticed that the vectors only support f32 floats:

rust-client/src/qdrant.rs

Lines 2037 to 2042 in cd7ee0f

#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Vector {
#[prost(float, repeated, tag = "1")]
pub data: ::prost::alloc::vec::Vec<f32>,
}

and I ran into an issue attempting to load PointStructs that are of Vec<f64> (using embeddings generated from an ollama rust client.

/// An embeddings generation response from Ollama.
#[derive(Debug, Deserialize, Clone)]
pub struct GenerateEmbeddingsResponse {
    #[serde(rename = "embedding")]
    #[allow(dead_code)]
    pub embeddings: Vec<f64>,
}

https://github.com/pepperoni21/ollama-rs/blob/f38634d33edd2ccdb440816aa866e5614a8a1983/src/generation/embeddings.rs#L54-L60

Trying to use this vec f64 results in:

error[E0277]: the trait bound `qdrant_client::qdrant::Vectors: From<Vec<f64>>` is not satisfied
    --> src/main.rs:99:42
     |
99   |     let point = vec![PointStruct::new(0, embedding_resp.embeddings, payload)];
     |                      ----------------    ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<Vec<f64>>` is not implemented for `qdrant_client::qdrant::Vectors`
     |                      |
     |                      required by a bound introduced by this call
     |
     = help: the following other types implement trait `From<T>`:
               <qdrant_client::qdrant::Vectors as From<HashMap<std::string::String, qdrant_client::qdrant::Vector>>>
               <qdrant_client::qdrant::Vectors as From<HashMap<std::string::String, Vec<f32>>>>
               <qdrant_client::qdrant::Vectors as From<HashMap<std::string::String, Vec<(u32, f32)>>>>
               <qdrant_client::qdrant::Vectors as From<HashMap<std::string::String, &[(u32, f32)]>>>
               <qdrant_client::qdrant::Vectors as From<Vec<f32>>>
     = note: required for `Vec<f64>` to implement `Into<qdrant_client::qdrant::Vectors>`
note: required by a bound in `client::<impl qdrant_client::prelude::PointStruct>::new`
    --> /home/jmcb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/qdrant-client-1.8.0/src/client.rs:1927:54
     |
1927 |     pub fn new(id: impl Into<PointId>, vectors: impl Into<Vectors>, payload: Payload) -> Self {
     |                                                      ^^^^^^^^^^^^^ required by this bound in `client::<impl PointStruct>::new`

For more information about this error, try `rustc --explain E0277`.
warning: `nvim-llama-qdrant-ctl` (bin "nvim-llama-qdrant-ctl") generated 1 warning
error: could not compile `nvim-llama-qdrant-ctl` (bin "nvim-llama-qdrant-ctl") due to 1 previous error; 1 warning emitted


Steps to reproduce

  1. Bootstrap qdrant client, collection, etc.
let qdrant_client = QdrantClient::from_url("http://localhost:6334").build()?;
let collection_name = "test";

qdrant_client
    .create_collection(&CreateCollection {
        collection_name: collection_name.into(),
        vectors_config: Some(VectorsConfig {
            config: Some(Config::Params(VectorParams {
                size:  384, // size of the all-minilm embeddings
                distance: Distance::Cosine.into(),
                ..Default::default()
            })),
        }),
        ..Default::default()
    })
    .await?;
  1. Bootstrap olllama client:
let ollama = Ollama::default();
let ollama = Ollama::new("http://localhost".to_string(), 11434);
  1. Generate an embedding using the ollama client - this is a Vec<f64>
let embedding_model = "all-minilm".to_string();
let embedding_prompt = "Woof woof, bark bark".to_string();
let embedding_resp = ollama
    .generate_embeddings(embedding_model, embedding_prompt, None)
    .await
    .unwrap();
  1. Attempt to use it in a PointStruct and notice error.
let payload: Payload = json!(
    {
        "test": "this is a test",
    }
)
    .try_into()
    .unwrap();

let point = vec![PointStruct::new(0, embedding_resp.embeddings, payload)];
client
    .upsert_points_blocking(collection_name, None, point, None)
    .await?;

Upsert operation is not being performed

Hello,

I have a bug in my implementation where no PointStructs that I define get upserted into the database.

The problem is that even with a "fresh" database, I get the error update operation failed and no vectors get added to the database. The error says "no existing vector name" but upsert should insert in that case, am I right ?

Where

I have a function called insert_points that converts a custom type I have to a PointStruct and attempts to upsert these pointstructs into the database. Each of the PointStructs has a NamedVector where the keys of the hashmap are.

  • a name,
  • a "{}:{}" the name and then a number.

So for example {"README": Vec<f32>, "README:0": Vec<f32>, "README:1": Vec<f32> }.
This error did not happen when I did not use NamedVectors and simply used Vector.

Logs

The log is as follows

           _                 _    
  __ _  __| |_ __ __ _ _ __ | |_  
 / _` |/ _` | '__/ _` | '_ \| __| 
| (_| | (_| | | | (_| | | | | |_  
 \__, |\__,_|_|  \__,_|_| |_|\__| 
    |_|                           

Access web UI at http://localhost:6333/dashboard

2023-11-21T12:40:26.652341Z  INFO storage::content_manager::consensus::persistent: Initializing new raft state at ./storage/raft_state.json    
2023-11-21T12:40:26.655909Z DEBUG storage::content_manager::consensus::persistent: State: Persistent { state: RaftState { hard_state: HardState { term: 0, vote: 0, commit: 0 }, conf_state: ConfState { voters: [834260950052035], learners: [], voters_outgoing: [], learners_next: [], auto_leave: false } }, latest_snapshot_meta: SnapshotMetadataSer { term: 0, index: 0 }, apply_progress_queue: EntryApplyProgressQueue(None), peer_address_by_id: RwLock { data: {} }, this_peer_id: 834260950052035, path: "./storage/raft_state.json", dirty: false }    
2023-11-21T12:40:26.658803Z  INFO qdrant: Distributed mode disabled    
2023-11-21T12:40:26.658816Z  INFO qdrant: Telemetry reporting disabled    
2023-11-21T12:40:26.658911Z DEBUG qdrant: Waiting for thread web to finish    
2023-11-21T12:40:26.659352Z  INFO qdrant::actix: TLS disabled for REST API    
2023-11-21T12:40:26.659491Z  INFO qdrant::actix: Qdrant HTTP listening on 6333    
2023-11-21T12:40:26.659500Z  INFO actix_server::builder: Starting 11 workers
2023-11-21T12:40:26.659508Z  INFO actix_server::server: Actix runtime found; starting in Actix runtime
2023-11-21T12:40:26.660786Z  INFO qdrant::tonic: Qdrant gRPC listening on 6334    
2023-11-21T12:40:26.660794Z  INFO qdrant::tonic: TLS disabled for gRPC API    
2023-11-21T12:41:10.265991Z DEBUG storage::content_manager::toc::collection_meta_ops: Creating collection fs    
2023-11-21T12:41:10.372934Z DEBUG segment::vector_storage::simple_vector_storage: Segment vectors: 0    
2023-11-21T12:41:10.372950Z DEBUG segment::vector_storage::simple_vector_storage: Estimated segment size 0 MB    
2023-11-21T12:41:10.374026Z DEBUG segment::vector_storage::simple_vector_storage: Segment vectors: 0    
2023-11-21T12:41:10.374035Z DEBUG segment::vector_storage::simple_vector_storage: Estimated segment size 0 MB    
2023-11-21T12:41:10.422461Z DEBUG collection::collection: Changing shard fs:0 replica state from Some(Initializing) to Active    
2023-11-21T12:41:10.422488Z DEBUG collection::shards::replica_set: Changing local shard fs:0 state from Some(Initializing) to Active    
2023-11-21T12:41:17.285251Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: README    
2023-11-21T12:41:17.286326Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: devin    
2023-11-21T12:41:17.287908Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: rivers:2    
2023-11-21T12:41:17.289641Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: O Captain:8    
2023-11-21T12:41:17.291052Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: goodbye:9    
2023-11-21T12:41:17.291782Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: man    
2023-11-21T12:41:17.292444Z  WARN collection::collection_manager::collection_updater: Update operation declined: Wrong input: Not existing vector name error: odyssey    

Any plan to support on the spot text embedding generation like FastEmbed?

Hi there.

I am glad for the FastEmbed / python-client integration. I am a little bit surprised that you did not choose Rust for the job though.

I am new to the Rust language. I needed to construct a tool to manage real-time text search through on-the-fly embedding creation, and handle bulk product image uploads through image embedding creation. I built this one; RustEmbed inspiring from qdrant RustSearch example and clip-as-service-rs.

Though the code is quite beginner-level and amateurish, it functions effectively. I am diligently refining the codebase daily to enhance its robustness. This service will be integrated atop Qdrant for our upcoming search project at a fashion e-commerce company, which caters to over 7 million customers and experiences around 1 million+ daily sessions, so it's imperative that it operates seamlessly.

Here is the progress for RustEmbed;

  • I converted the patrickjohncyh/fashion-clip model to ONNX with Optimum
  • Used pykeio/ort for the ONNX environment
  • Utilized tonic+tokio for gRPC
  • Freshly refactoring the code to modularize it for further features like supporting more models, Rest API, etc.

What I am trying to say is, if you happen to decide on a Rust-based embedding service, and put together a team around it, I would gladly contribute.

Outdated example

The Filter conditions seem to have changed drastically compared to the example. There are now structs and enums instead of functions.

Specifically:

let search_result = client
        .search_points(&SearchPoints {
            collection_name: collection_name.into(),
            vector: vec![11.; 10],
            filter: Some(Filter::all([Condition::matches("bar", 12)])),
            limit: 10,
            ..Default::default()
        })
        .await?;

Build with qdrant-client fails

How to reproduce

  • Create a new Rust application: cargo new test-qdrant-client
  • Add qdrant-client as specified in docs: cargo add qdrant-client
  • Build app: cargo build

Expected result

App builds successfully, prints Hello World

Actual result

Build fails with message Error: Custom { kind: Other, error: "protoc failed: collections.proto:73:12: Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields are 'optional' by default.\n...

Environment

Identical behavior with rust stable (rustc 1.67.1) and rust nightly (rustc 1.69.0-nightly).

Local Qdrant

Hi!

I'm curious whether there's any intention of adding support of a local qdrant setup for Rust, like there is for Python3. I would love to use qdrant for a project I'm working on and it would definitely be a huge convenience!

from qdrant_client import QdrantClient
client = QdrantClient(path="path/to/db")  # Persists changes to disk, fast prototyping

Thanks for building this awesome database!

Cheers.

Better documentation

I am a Rust user and I am becoming a qdrant fan. I want to use qdrant in a production project with Rust. Unfortunately I miss a beter documentation where not only examples but possibilities and how to use types are covered.

Wich are the available features of the crate, what does each function does, what each type does and how to create them from other common types like vectors and serde_json::Value, these are just some examples of questions that could be answered in a beter documentation.

I would like to help with that, but I will need the help of the developers to create that.

[bug] upsert_points_blocking() api blocks indefinitely without any clear debug message

Hey folks,

I'm creating a custom payload and committing data to Qdrant. The upsert operation works perfectly for about a thousand points, then gets blocked indefinitely. There was no debug information available to identify what could have gone wrong.

  client
             .upsert_points_blocking(COLLECTION_NAME, new, None)
             .await
             .map_err(|_| Box::new(CommitError::QdrantError))?;

Working with qdrant::Value

Hi, thanks for the rust client. However, I'm not sure how to work with qdrant_client::qdrant::Value. I would like to convert back to a rust type. Please help.
Also, it would be really helpful if detailed examples (like how it is done for the python client) can be added for the rust client. Thanks!

Rust client can't connect to Qdrant Cloud

I'm using Rust's client v1.9.0, and when I try to connect to the cloud cluster I get an error message:

status: Unimplemented, message: "grpc-status header missing, mapped from HTTP status code 404", details: [], metadata: MetadataMap { headers: {"date": "Wed, 15 May 2024 20:34:00 GMT", "vary": "Origin, Access-Control-Request-Method, Access-Control-Request-Headers", "content-length": "0"} }

Here's how I'm initializing the client:

let client_config = QdrantClientConfig::from_url(config.address.as_deref().unwrap_or("http://localhost:6334")).with_api_key(config.api_key.as_ref());
let client = QdrantClient::new(Some(client_config))?;

Sounds like this version of the SDK is not compatible. When CURLing the health endpoint, I get that the cluster is running on version 1.9.2.

Rust client does not work with trunk

Reproduce steps:

rustup target add wasm32-unknown-unknown
cargo install trunk
cargo new repo
cd repo
cargo add qdrant-client
echo '<!DOCTYPE html><html><head></head><body></body></html>' > index.html
trunk serve # or cargo build --target wasm32-unknown-unknown

Errors:

warning: unused config key `source.rsproxy.index` in `/Users/user/.cargo/config.toml`
warning: unused config key `source.rsproxy-sparse.index` in `/Users/user/.cargo/config.toml`
   Compiling mio v0.8.11
   Compiling proc-macro2 v1.0.86
   Compiling getrandom v0.2.15
   Compiling slab v0.4.9
   Compiling wasm-bindgen-shared v0.2.92
   Compiling http v0.2.12
   Compiling wasm-bindgen v0.2.92
   Compiling tower-service v0.3.2
   Compiling rustversion v1.0.17
   Compiling ring v0.17.8
   Compiling tracing-core v0.1.32
   Compiling serde v1.0.203
error: the wasm*-unknown-unknown targets are not supported by default, you may need to enable the "js" feature. For more information see: https://docs.rs/getrandom/#webassembly-support
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/getrandom-0.2.15/src/lib.rs:342:9
    |
342 | /         compile_error!("the wasm*-unknown-unknown targets are not supported by \
343 | |                         default, you may need to enable the \"js\" feature. \
344 | |                         For more information see: \
345 | |                         https://docs.rs/getrandom/#webassembly-support");
    | |________________________________________________________________________^

error[E0432]: unresolved import `crate::sys::IoSourceState`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:12:5
   |
12 | use crate::sys::IoSourceState;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ no `IoSourceState` in `sys`

error[E0432]: unresolved import `crate::sys::tcp`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:15:17
   |
15 | use crate::sys::tcp::{bind, listen, new_for_addr};
   |                 ^^^ could not find `tcp` in `sys`

error[E0432]: unresolved import `crate::sys::tcp`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/stream.rs:13:17
   |
13 | use crate::sys::tcp::{connect, new_for_addr};
   |                 ^^^ could not find `tcp` in `sys`

error[E0433]: failed to resolve: could not find `Selector` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/poll.rs:312:18
    |
312 |             sys::Selector::new().map(|selector| Poll {
    |                  ^^^^^^^^ could not find `Selector` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:24:14
   |
24 |         sys::event::token(&self.inner)
   |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:38:14
   |
38 |         sys::event::is_readable(&self.inner)
   |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:43:14
   |
43 |         sys::event::is_writable(&self.inner)
   |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:68:14
   |
68 |         sys::event::is_error(&self.inner)
   |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:99:14
   |
99 |         sys::event::is_read_closed(&self.inner)
   |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:129:14
    |
129 |         sys::event::is_write_closed(&self.inner)
    |              ^^^^^ could not find `event` in `sys`

   Compiling percent-encoding v2.3.1
error[E0433]: failed to resolve: could not find `event` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:151:14
    |
151 |         sys::event::is_priority(&self.inner)
    |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:173:14
    |
173 |         sys::event::is_aio(&self.inner)
    |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: use of undeclared crate or module `imp`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/getrandom-0.2.15/src/lib.rs:398:9
    |
398 |         imp::getrandom_inner(dest)?;
    |         ^^^ use of undeclared crate or module `imp`

error[E0433]: failed to resolve: could not find `event` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:183:14
    |
183 |         sys::event::is_lio(&self.inner)
    |              ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `event` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:221:26
    |
221 |                     sys::event::debug_details(f, self.0)
    |                          ^^^^^ could not find `event` in `sys`

error[E0433]: failed to resolve: could not find `tcp` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:103:18
    |
103 |             sys::tcp::accept(inner).map(|(stream, addr)| (TcpStream::from_std(stream), addr))
    |                  ^^^ could not find `tcp` in `sys`

For more information about this error, try `rustc --explain E0433`.
error[E0433]: failed to resolve: could not find `udp` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/udp.rs:122:14
    |
122 |         sys::udp::bind(addr).map(UdpSocket::from_std)
    |              ^^^ could not find `udp` in `sys`

error[E0433]: failed to resolve: could not find `udp` in `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/udp.rs:544:14
    |
544 |         sys::udp::only_v6(&self.inner)
    |              ^^^ could not find `udp` in `sys`

error[E0412]: cannot find type `Selector` in module `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/poll.rs:263:20
    |
263 |     selector: sys::Selector,
    |                    ^^^^^^^^ not found in `sys`

error[E0412]: cannot find type `Selector` in module `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/poll.rs:710:44
    |
710 |     pub(crate) fn selector(&self) -> &sys::Selector {
    |                                            ^^^^^^^^ not found in `sys`

error: could not compile `getrandom` (lib) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
error[E0412]: cannot find type `Waker` in module `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/waker.rs:79:17
   |
79 |     inner: sys::Waker,
   |                 ^^^^^ not found in `sys`
   |
help: consider importing one of these items
   |
1  + use core::task::Waker;
   |
1  + use crate::Waker;
   |
1  + use std::task::Waker;
   |
help: if you import `Waker`, refer to it directly
   |
79 -     inner: sys::Waker,
79 +     inner: Waker,
   |

error[E0433]: failed to resolve: could not find `Waker` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/waker.rs:87:14
   |
87 |         sys::Waker::new(registry.selector(), token).map(|inner| Waker { inner })
   |              ^^^^^ could not find `Waker` in `sys`
   |
help: consider importing one of these items
   |
1  + use core::task::Waker;
   |
1  + use crate::Waker;
   |
1  + use std::task::Waker;
   |
help: if you import `Waker`, refer to it directly
   |
87 -         sys::Waker::new(registry.selector(), token).map(|inner| Waker { inner })
87 +         Waker::new(registry.selector(), token).map(|inner| Waker { inner })
   |

error[E0412]: cannot find type `Event` in module `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:18:17
   |
18 |     inner: sys::Event,
   |                 ^^^^^ not found in `sys`
   |
help: consider importing this struct through its public re-export
   |
1  + use crate::event::Event;
   |
help: if you import `Event`, refer to it directly
   |
18 -     inner: sys::Event,
18 +     inner: Event,
   |

error[E0412]: cannot find type `Event` in module `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:187:55
    |
187 |     pub(crate) fn from_sys_event_ref(sys_event: &sys::Event) -> &Event {
    |                                                       ^^^^^ not found in `sys`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::event::Event;
    |
help: if you import `Event`, refer to it directly
    |
187 -     pub(crate) fn from_sys_event_ref(sys_event: &sys::Event) -> &Event {
187 +     pub(crate) fn from_sys_event_ref(sys_event: &Event) -> &Event {
    |

error[E0412]: cannot find type `Event` in module `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:191:41
    |
191 |             &*(sys_event as *const sys::Event as *const Event)
    |                                         ^^^^^ not found in `sys`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::event::Event;
    |
help: if you import `Event`, refer to it directly
    |
191 -             &*(sys_event as *const sys::Event as *const Event)
191 +             &*(sys_event as *const Event as *const Event)
    |

error[E0412]: cannot find type `Event` in module `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/event.rs:217:46
    |
217 |             struct EventDetails<'a>(&'a sys::Event);
    |                                              ^^^^^ not found in `sys`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::event::Event;
    |
help: if you import `Event`, refer to it directly
    |
217 -             struct EventDetails<'a>(&'a sys::Event);
217 +             struct EventDetails<'a>(&'a Event);
    |

error[E0412]: cannot find type `Events` in module `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/events.rs:43:17
   |
43 |     inner: sys::Events,
   |                 ^^^^^^ not found in `sys`
   |
help: consider importing this struct through its public re-export
   |
1  + use crate::Events;
   |
help: if you import `Events`, refer to it directly
   |
43 -     inner: sys::Events,
43 +     inner: Events,
   |

error[E0433]: failed to resolve: could not find `Events` in `sys`
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/events.rs:94:25
   |
94 |             inner: sys::Events::with_capacity(capacity),
   |                         ^^^^^^ could not find `Events` in `sys`
   |
help: consider importing this struct through its public re-export
   |
1  + use crate::Events;
   |
help: if you import `Events`, refer to it directly
   |
94 -             inner: sys::Events::with_capacity(capacity),
94 +             inner: Events::with_capacity(capacity),
   |

error[E0412]: cannot find type `Events` in module `sys`
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/events.rs:189:47
    |
189 |     pub(crate) fn sys(&mut self) -> &mut sys::Events {
    |                                               ^^^^^^ not found in `sys`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::Events;
    |
help: if you import `Events`, refer to it directly
    |
189 -     pub(crate) fn sys(&mut self) -> &mut sys::Events {
189 +     pub(crate) fn sys(&mut self) -> &mut Events {
    |

error[E0425]: cannot find value `listener` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:74:24
   |
74 |         set_reuseaddr(&listener.inner, true)?;
   |                        ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `listener` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:76:15
   |
76 |         bind(&listener.inner, addr)?;
   |               ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `listener` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:77:17
   |
77 |         listen(&listener.inner, 1024)?;
   |                 ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `listener` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:78:12
   |
78 |         Ok(listener)
   |            ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `stream` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/stream.rs:90:18
   |
90 |         connect(&stream.inner, addr)?;
   |                  ^^^^^^ not found in this scope

error[E0425]: cannot find value `stream` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/stream.rs:91:12
   |
91 |         Ok(stream)
   |            ^^^^^^ not found in this scope

error[E0425]: cannot find function `set_reuseaddr` in this scope
  --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:74:9
   |
74 |         set_reuseaddr(&listener.inner, true)?;
   |         ^^^^^^^^^^^^^ not found in this scope

error[E0599]: no method named `register` found for struct `IoSource<std::net::TcpListener>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:146:20
    |
146 |         self.inner.register(registry, token, interests)
    |                    ^^^^^^^^ method not found in `IoSource<TcpListener>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `register` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `register`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `reregister` found for struct `IoSource<std::net::TcpListener>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:155:20
    |
155 |         self.inner.reregister(registry, token, interests)
    |                    ^^^^^^^^^^ method not found in `IoSource<TcpListener>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `reregister` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `reregister`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `deregister` found for struct `IoSource<std::net::TcpListener>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/listener.rs:159:20
    |
159 |         self.inner.deregister(registry)
    |                    ^^^^^^^^^^ method not found in `IoSource<TcpListener>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `deregister` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `deregister`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `register` found for struct `IoSource<std::net::TcpStream>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/stream.rs:325:20
    |
325 |         self.inner.register(registry, token, interests)
    |                    ^^^^^^^^ method not found in `IoSource<TcpStream>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `register` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `register`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `reregister` found for struct `IoSource<std::net::TcpStream>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/stream.rs:334:20
    |
334 |         self.inner.reregister(registry, token, interests)
    |                    ^^^^^^^^^^ method not found in `IoSource<TcpStream>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `reregister` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `reregister`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `deregister` found for struct `IoSource<std::net::TcpStream>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/tcp/stream.rs:338:20
    |
338 |         self.inner.deregister(registry)
    |                    ^^^^^^^^^^ method not found in `IoSource<TcpStream>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `deregister` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `deregister`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `register` found for struct `IoSource<std::net::UdpSocket>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/udp.rs:622:20
    |
622 |         self.inner.register(registry, token, interests)
    |                    ^^^^^^^^ method not found in `IoSource<UdpSocket>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `register` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `register`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `reregister` found for struct `IoSource<std::net::UdpSocket>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/udp.rs:631:20
    |
631 |         self.inner.reregister(registry, token, interests)
    |                    ^^^^^^^^^^ method not found in `IoSource<UdpSocket>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `reregister` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `reregister`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

error[E0599]: no method named `deregister` found for struct `IoSource<std::net::UdpSocket>` in the current scope
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/net/udp.rs:635:20
    |
635 |         self.inner.deregister(registry)
    |                    ^^^^^^^^^^ method not found in `IoSource<UdpSocket>`
    |
   ::: /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/io_source.rs:62:1
    |
62  | pub struct IoSource<T> {
    | ---------------------- method `deregister` not found for this struct
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `Source` defines an item `deregister`, perhaps you need to implement it
   --> /Users/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/mio-0.8.11/src/event/source.rs:75:1
    |
75  | pub trait Source {
    | ^^^^^^^^^^^^^^^^

Some errors have detailed explanations: E0412, E0425, E0432, E0433, E0599.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `mio` (lib) due to 44 previous errors

Serde json support

Please add serde json support. Serializing de-serializing payload is extremely painful right now. There is a Value class that is included but there is no support for serializing from json string. Why reinvent the wheel when you can use serde json to do all of that easily. The Value pattern is exactly what serde json already uses for unstructured json data.

Use a more fitting error type

Currently this crate uses anyhow, which is usually meant for applications, not libraries. This makes it very hard to match on an error, because the error is essentially opaque. As far as I can see, we mostly return ´tonic::Status`, but there may be some APIs that also can return other errors.

The classic way of dealing with this is create a newtype that wraps Status, has a From<Status> impl and allows basically the same functionality (especially matching on Code). We could also create an enum instead, but I should note that this will either make the implementation, the user interface or both needlessly complex. If we have API calls that can return other errors, either have them return their own specific error type or convert whatever error we get to our predefined error type internally.

Another way would be to make the error type opaque, but that has the downside of making it harder for users to implement From<QdrantError> for their own error types, essentially requiring a Box or other indirection.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.