Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/serverless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async fn main() -> Result<(), QdrantError> {
.payload_index("color", KeywordIndex::new()),
)
.await?;
println!("create_collection: {result}");
println!("create_collection: {result:?}");

println!(
"collections: {:?}",
Expand Down
8 changes: 8 additions & 0 deletions proto/serverless_collections.proto
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ message CreateCollectionResponse {
string collection_name = 1;
// Outcome, e.g. "created", "already exists".
string result = 2;
// Time spent to process
double time = 3;
}

// Names the collection to delete.
Expand All @@ -238,6 +240,8 @@ message DeleteCollectionResponse {
bool deleted = 1;
// Number of storage objects removed.
uint32 objects_deleted = 2;
// Time spent to process
double time = 3;
}

// Names the collection to fetch.
Expand All @@ -255,6 +259,8 @@ message GetCollectionResponse {
// Available points as of the last applied write (eventually consistent);
// absent until the updater has written stats for the collection.
optional uint64 point_count = 3;
// Time spent to process
double time = 4;
}

// Lists the caller's collections. The tenant travels in metadata.
Expand Down Expand Up @@ -283,4 +289,6 @@ message ListCollectionsResponse {
// Opaque token to pass as `offset_token` to retrieve the next page. Absent
// when there are no more results.
optional string next_offset_token = 2;
// Time spent to process
double time = 3;
}
29 changes: 18 additions & 11 deletions src/serverless/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ use crate::serverless::grpc::{
CreateCollectionRequest, DeleteCollectionRequest, GetCollectionRequest, ListCollectionsRequest,
};
use crate::serverless::models::{
CollectionConfig, CollectionInfo, CollectionSummary, CollectionsList, ListCollections,
CollectionConfig, CollectionInfo, CollectionSummary, CollectionsList, CreateCollectionResult,
DeleteCollectionResult, ListCollections,
};
use crate::Qdrant;

Expand Down Expand Up @@ -217,39 +218,43 @@ impl QdrantServerless {
/// At least one dense or sparse vector is required. Unlike the regular client,
/// no storage internals (quantization, WAL, segment number, ...) can be
/// configured: the serverless manager decides those.
///
/// Returns the outcome string from the service (e.g. `"created"`).
pub async fn create_collection(
&self,
collection_name: impl Into<String>,
config: CollectionConfig,
) -> QdrantResult<String> {
) -> QdrantResult<CreateCollectionResult> {
let request = CreateCollectionRequest {
collection_name: collection_name.into(),
config: Some(collection_config_to_grpc(&config)),
};
let request = &request;
self.with_collections_client(|mut api| async move {
let response = api.create_collection(request.clone()).await?;
Ok(response.into_inner().result)
let response = api.create_collection(request.clone()).await?.into_inner();
Ok(CreateCollectionResult {
collection_name: response.collection_name,
result: response.result,
time: response.time,
})
})
.await
}

/// Deletes a collection and all of its data.
///
/// Returns `true` if the collection existed and was deleted, `false` otherwise.
pub async fn delete_collection(
&self,
collection_name: impl Into<String>,
) -> QdrantResult<bool> {
) -> QdrantResult<DeleteCollectionResult> {
let request = DeleteCollectionRequest {
collection_name: collection_name.into(),
};
let request = &request;
self.with_collections_client(|mut api| async move {
let response = api.delete_collection(request.clone()).await?;
Ok(response.into_inner().deleted)
let response = api.delete_collection(request.clone()).await?.into_inner();
Ok(DeleteCollectionResult {
deleted: response.deleted,
objects_deleted: response.objects_deleted,
time: response.time,
})
})
.await
}
Expand Down Expand Up @@ -279,6 +284,7 @@ impl QdrantServerless {
.map(collection_config_from_grpc)
.transpose()?,
point_count: response.point_count,
time: response.time,
})
}

Expand Down Expand Up @@ -334,6 +340,7 @@ impl QdrantServerless {
})
.collect(),
next_offset_token: response.next_offset_token,
time: response.time,
})
})
.await
Expand Down
16 changes: 14 additions & 2 deletions src/serverless/grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,17 @@ pub struct CreateCollectionRequest {
pub config: ::core::option::Option<CollectionConfig>,
}
/// Result of a create.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CreateCollectionResponse {
/// Tenant-facing name of the collection.
#[prost(string, tag = "1")]
pub collection_name: ::prost::alloc::string::String,
/// Outcome, e.g. "created", "already exists".
#[prost(string, tag = "2")]
pub result: ::prost::alloc::string::String,
/// Time spent to process
#[prost(double, tag = "3")]
pub time: f64,
}
/// Names the collection to delete.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
Expand All @@ -230,14 +233,17 @@ pub struct DeleteCollectionRequest {
pub collection_name: ::prost::alloc::string::String,
}
/// Result of a delete.
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct DeleteCollectionResponse {
/// Whether the collection existed and was deleted.
#[prost(bool, tag = "1")]
pub deleted: bool,
/// Number of storage objects removed.
#[prost(uint32, tag = "2")]
pub objects_deleted: u32,
/// Time spent to process
#[prost(double, tag = "3")]
pub time: f64,
}
/// Names the collection to fetch.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
Expand All @@ -259,6 +265,9 @@ pub struct GetCollectionResponse {
/// absent until the updater has written stats for the collection.
#[prost(uint64, optional, tag = "3")]
pub point_count: ::core::option::Option<u64>,
/// Time spent to process
#[prost(double, tag = "4")]
pub time: f64,
}
/// Lists the caller's collections. The tenant travels in metadata.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
Expand Down Expand Up @@ -293,6 +302,9 @@ pub struct ListCollectionsResponse {
/// when there are no more results.
#[prost(string, optional, tag = "2")]
pub next_offset_token: ::core::option::Option<::prost::alloc::string::String>,
/// Time spent to process
#[prost(double, tag = "3")]
pub time: f64,
}
/// Distance metric used to compare dense vectors.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
Expand Down
10 changes: 5 additions & 5 deletions src/serverless/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ pub mod models;

pub use client::{QdrantServerless, QdrantServerlessBuilder, DEFAULT_SERVERLESS_GRPC_PORT};
pub use models::{
BoolIndex, CollectionConfig, CollectionInfo, CollectionSummary, CollectionsList, DatetimeIndex,
DenseVectorConfig, Distance, FloatIndex, GeoIndex, IntegerIndex, KeywordIndex,
KeywordPrefixParams, ListCollections, ListCollectionsBuilder, PayloadIndex, PrecisionTier,
SnowballParams, SparseVectorConfig, StemmingAlgorithm, StopwordsSet, TextIndex, Tokenizer,
UuidIndex,
BoolIndex, CollectionConfig, CollectionInfo, CollectionSummary, CollectionsList,
CreateCollectionResult, DatetimeIndex, DeleteCollectionResult, DenseVectorConfig, Distance,
FloatIndex, GeoIndex, IntegerIndex, KeywordIndex, KeywordPrefixParams, ListCollections,
ListCollectionsBuilder, PayloadIndex, PrecisionTier, SnowballParams, SparseVectorConfig,
StemmingAlgorithm, StopwordsSet, TextIndex, Tokenizer, UuidIndex,
};
32 changes: 30 additions & 2 deletions src/serverless/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,16 +422,42 @@ impl CollectionConfig {
}
}

/// Result of [`super::QdrantServerless::create_collection`].
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CreateCollectionResult {
/// Tenant-facing name of the collection.
pub collection_name: String,
/// Outcome, e.g. `"created"`.
pub result: String,
/// Time spent to process the request, in seconds.
pub time: f64,
}

/// Result of [`super::QdrantServerless::delete_collection`].
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DeleteCollectionResult {
/// Whether the collection existed and was deleted.
pub deleted: bool,
/// Number of storage objects removed.
pub objects_deleted: u32,
/// Time spent to process the request, in seconds.
pub time: f64,
}

/// A collection's configuration and stats, as returned by [`super::QdrantServerless::get_collection`].
///
/// `point_count` is eventually consistent and absent until stats have been
/// written for the collection.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CollectionInfo {
pub exists: bool,
pub config: Option<CollectionConfig>,
pub point_count: Option<u64>,
/// Time spent to process the request, in seconds.
pub time: f64,
}

/// Request for [`super::QdrantServerless::list_collections`].
Expand Down Expand Up @@ -504,10 +530,12 @@ pub struct CollectionSummary {
}

/// A page of collections returned by [`super::QdrantServerless::list_collections`].
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CollectionsList {
pub collections: Vec<CollectionSummary>,
/// Opaque token to pass as `offset_token` for the next page. Absent when done.
pub next_offset_token: Option<String>,
/// Time spent to process the request, in seconds.
pub time: f64,
}
Loading