Skip to content

Commit a8b5448

Browse files
generalltimvisee
andauthored
implement conversions for inference objects (#226)
* implement conversions for inference objects * fmt * Update src/builders/document_builder.rs Co-authored-by: Tim Visée <tim@visee.me> * Update src/builders/image_builder.rs Co-authored-by: Tim Visée <tim@visee.me> --------- Co-authored-by: Tim Visée <tim@visee.me>
1 parent f70fcc3 commit a8b5448

File tree

14 files changed

+462
-2
lines changed

14 files changed

+462
-2
lines changed

src/builders/document_builder.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use std::collections::HashMap;
2+
3+
use crate::qdrant::{Document, Value};
4+
5+
impl Document {
6+
pub fn new(text: impl Into<String>, model: impl Into<String>) -> Self {
7+
Self {
8+
text: text.into(),
9+
model: model.into(),
10+
options: HashMap::new(),
11+
}
12+
}
13+
}
14+
15+
pub struct DocumentBuilder {
16+
text: String,
17+
model: String,
18+
options: HashMap<String, Value>,
19+
}
20+
21+
impl DocumentBuilder {
22+
pub fn new(text: impl Into<String>, model: impl Into<String>) -> Self {
23+
Self {
24+
text: text.into(),
25+
model: model.into(),
26+
options: HashMap::new(),
27+
}
28+
}
29+
30+
pub fn text(mut self, text: impl Into<String>) -> Self {
31+
self.text = text.into();
32+
self
33+
}
34+
35+
pub fn model(mut self, model: impl Into<String>) -> Self {
36+
self.model = model.into();
37+
self
38+
}
39+
40+
pub fn options(mut self, options: HashMap<String, Value>) -> Self {
41+
self.options = options;
42+
self
43+
}
44+
45+
pub fn build(self) -> Document {
46+
Document {
47+
text: self.text,
48+
model: self.model,
49+
options: self.options,
50+
}
51+
}
52+
}

src/builders/image_builder.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use std::collections::HashMap;
2+
3+
use crate::qdrant::{value, Image, Value};
4+
5+
impl Image {
6+
pub fn new_from_url(url: impl Into<String>, model: impl Into<String>) -> Self {
7+
Self {
8+
image: Some(Value {
9+
kind: Some(value::Kind::StringValue(url.into())),
10+
}),
11+
model: model.into(),
12+
options: HashMap::new(),
13+
}
14+
}
15+
16+
pub fn new_from_base64(base64: impl Into<String>, model: impl Into<String>) -> Self {
17+
Self {
18+
image: Some(Value {
19+
kind: Some(value::Kind::StringValue(base64.into())),
20+
}),
21+
model: model.into(),
22+
options: HashMap::new(),
23+
}
24+
}
25+
}
26+
27+
pub struct ImageBuilder {
28+
image: Option<Value>,
29+
model: String,
30+
options: HashMap<String, Value>,
31+
}
32+
33+
impl ImageBuilder {
34+
pub fn new_from_url(url: impl Into<String>, model: impl Into<String>) -> Self {
35+
Self {
36+
image: Some(Value {
37+
kind: Some(value::Kind::StringValue(url.into())),
38+
}),
39+
model: model.into(),
40+
options: HashMap::new(),
41+
}
42+
}
43+
44+
pub fn new_from_base64(base64: impl Into<String>, model: impl Into<String>) -> Self {
45+
Self {
46+
image: Some(Value {
47+
kind: Some(value::Kind::StringValue(base64.into())),
48+
}),
49+
model: model.into(),
50+
options: HashMap::new(),
51+
}
52+
}
53+
54+
pub fn image(mut self, image: Value) -> Self {
55+
self.image = Some(image);
56+
self
57+
}
58+
59+
pub fn model(mut self, model: impl Into<String>) -> Self {
60+
self.model = model.into();
61+
self
62+
}
63+
64+
pub fn options(mut self, options: HashMap<String, Value>) -> Self {
65+
self.options = options;
66+
self
67+
}
68+
69+
pub fn build(self) -> Image {
70+
Image {
71+
image: self.image,
72+
model: self.model,
73+
options: self.options,
74+
}
75+
}
76+
}

src/builders/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,9 @@ pub use sparse_vector_builder::SparseVectorBuilder;
237237

238238
pub mod multi_dense_vector_builder;
239239
pub use multi_dense_vector_builder::MultiDenseVectorBuilder;
240+
241+
pub mod document_builder;
242+
pub use document_builder::DocumentBuilder;
243+
244+
pub mod image_builder;
245+
pub use image_builder::ImageBuilder;

src/qdrant_client/conversions/vector_input.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::qdrant::{PointId, VectorInput};
1+
use crate::qdrant::{vector_input, Document, Image, InferenceObject, PointId, VectorInput};
22

33
impl<T: Into<PointId>> From<T> for VectorInput {
44
fn from(value: T) -> Self {
@@ -24,3 +24,27 @@ impl From<Vec<Vec<f32>>> for VectorInput {
2424
Self::new_multi(value)
2525
}
2626
}
27+
28+
impl From<Document> for VectorInput {
29+
fn from(value: Document) -> Self {
30+
VectorInput {
31+
variant: Some(vector_input::Variant::Document(value)),
32+
}
33+
}
34+
}
35+
36+
impl From<Image> for VectorInput {
37+
fn from(value: Image) -> Self {
38+
VectorInput {
39+
variant: Some(vector_input::Variant::Image(value)),
40+
}
41+
}
42+
}
43+
44+
impl From<InferenceObject> for VectorInput {
45+
fn from(value: InferenceObject) -> Self {
46+
VectorInput {
47+
variant: Some(vector_input::Variant::Object(value)),
48+
}
49+
}
50+
}

src/qdrant_client/conversions/vectors.rs

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::HashMap;
22

33
use crate::qdrant::vectors::VectorsOptions;
4-
use crate::qdrant::{NamedVectors, Vector, Vectors};
4+
use crate::qdrant::{vector, Document, Image, InferenceObject, NamedVectors, Vector, Vectors};
55

66
impl From<Vec<f32>> for Vector {
77
fn from(vector: Vec<f32>) -> Self {
@@ -139,3 +139,93 @@ impl From<NamedVectors> for VectorsOptions {
139139
Self::Vectors(value)
140140
}
141141
}
142+
143+
impl From<Document> for Vector {
144+
fn from(value: Document) -> Self {
145+
Vector {
146+
vector: Some(vector::Vector::Document(value)),
147+
..Default::default()
148+
}
149+
}
150+
}
151+
152+
impl From<Document> for Vectors {
153+
fn from(value: Document) -> Self {
154+
Vectors {
155+
vectors_options: Some(VectorsOptions::Vector(Vector::from(value))),
156+
}
157+
}
158+
}
159+
160+
impl From<HashMap<String, Document>> for Vectors {
161+
fn from(value: HashMap<String, Document>) -> Self {
162+
Vectors {
163+
vectors_options: Some(VectorsOptions::Vectors(NamedVectors {
164+
vectors: value
165+
.into_iter()
166+
.map(|(k, v)| (k, Vector::from(v)))
167+
.collect(),
168+
})),
169+
}
170+
}
171+
}
172+
173+
impl From<Image> for Vector {
174+
fn from(value: Image) -> Self {
175+
Vector {
176+
vector: Some(vector::Vector::Image(value)),
177+
..Default::default()
178+
}
179+
}
180+
}
181+
182+
impl From<Image> for Vectors {
183+
fn from(value: Image) -> Self {
184+
Vectors {
185+
vectors_options: Some(VectorsOptions::Vector(Vector::from(value))),
186+
}
187+
}
188+
}
189+
190+
impl From<HashMap<String, Image>> for Vectors {
191+
fn from(value: HashMap<String, Image>) -> Self {
192+
Vectors {
193+
vectors_options: Some(VectorsOptions::Vectors(NamedVectors {
194+
vectors: value
195+
.into_iter()
196+
.map(|(k, v)| (k, Vector::from(v)))
197+
.collect(),
198+
})),
199+
}
200+
}
201+
}
202+
203+
impl From<InferenceObject> for Vector {
204+
fn from(value: InferenceObject) -> Self {
205+
Vector {
206+
vector: Some(vector::Vector::Object(value)),
207+
..Default::default()
208+
}
209+
}
210+
}
211+
212+
impl From<InferenceObject> for Vectors {
213+
fn from(value: InferenceObject) -> Self {
214+
Vectors {
215+
vectors_options: Some(VectorsOptions::Vector(Vector::from(value))),
216+
}
217+
}
218+
}
219+
220+
impl From<HashMap<String, InferenceObject>> for Vectors {
221+
fn from(value: HashMap<String, InferenceObject>) -> Self {
222+
Vectors {
223+
vectors_options: Some(VectorsOptions::Vectors(NamedVectors {
224+
vectors: value
225+
.into_iter()
226+
.map(|(k, v)| (k, Vector::from(v)))
227+
.collect(),
228+
})),
229+
}
230+
}
231+
}

tests/snippet_tests/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ mod test_get_points;
2626
mod test_list_full_snapshots;
2727
mod test_list_snapshots;
2828
mod test_overwrite_payload;
29+
mod test_query_document;
30+
mod test_query_image;
2931
mod test_query_points;
3032
mod test_query_points_groups;
3133
mod test_recommend_batch_points;
@@ -41,4 +43,6 @@ mod test_set_payload;
4143
mod test_update_aliases;
4244
mod test_update_collection;
4345
mod test_update_vectors;
46+
mod test_upsert_document;
47+
mod test_upsert_image;
4448
mod test_upsert_points;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
#[tokio::test]
3+
async fn test_query_document() {
4+
async fn query_document() -> Result<(), Box<dyn std::error::Error>> {
5+
// WARNING: This is a generated test snippet.
6+
// Please, modify the snippet in the `../snippets/query_document.rs` file
7+
use qdrant_client::qdrant::{Document, Query, QueryPointsBuilder};
8+
use qdrant_client::Qdrant;
9+
10+
let client = Qdrant::from_url("http://localhost:6334").build()?;
11+
12+
let query_document = Document::new(
13+
"my query text",
14+
"sentence-transformers/all-minilm-l6-v2"
15+
);
16+
17+
let query_request = QueryPointsBuilder::new("{collection_name}")
18+
.query(Query::new_nearest(query_document));
19+
20+
// ANN search with server-side inference
21+
client.query(query_request).await?;
22+
23+
Ok(())
24+
}
25+
let _ = query_document().await;
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
#[tokio::test]
3+
async fn test_query_image() {
4+
async fn query_image() -> Result<(), Box<dyn std::error::Error>> {
5+
// WARNING: This is a generated test snippet.
6+
// Please, modify the snippet in the `../snippets/query_image.rs` file
7+
use qdrant_client::qdrant::{Image, Query, QueryPointsBuilder};
8+
use qdrant_client::Qdrant;
9+
10+
let client = Qdrant::from_url("http://localhost:6334").build()?;
11+
12+
let query_image = Image::new_from_url(
13+
"https://picsum.photos/200/300.jpg",
14+
"Qdrant/clip-ViT-B-32-vision"
15+
);
16+
17+
let query_request = QueryPointsBuilder::new("{collection_name}")
18+
.query(Query::new_nearest(query_image));
19+
20+
// ANN search with server-side inference
21+
client.query(query_request).await?;
22+
23+
Ok(())
24+
}
25+
let _ = query_image().await;
26+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
#[tokio::test]
3+
async fn test_upsert_document() {
4+
async fn upsert_document() -> Result<(), Box<dyn std::error::Error>> {
5+
// WARNING: This is a generated test snippet.
6+
// Please, modify the snippet in the `../snippets/upsert_document.rs` file
7+
use qdrant_client::qdrant::{PointStruct, UpsertPointsBuilder, Document};
8+
use qdrant_client::{Qdrant, Payload};
9+
use serde_json::json;
10+
11+
let client = Qdrant::from_url("http://localhost:6334").build()?;
12+
13+
let document = Document::new("my document", "sentence-transformers/all-minilm-l6-v2");
14+
15+
client
16+
.upsert_points(
17+
UpsertPointsBuilder::new(
18+
"{collection_name}",
19+
vec![
20+
PointStruct::new(
21+
1,
22+
document,
23+
Payload::try_from(json!(
24+
{"color": "red"}
25+
))
26+
.unwrap(),
27+
)
28+
],
29+
)
30+
.wait(true),
31+
)
32+
.await?;
33+
Ok(())
34+
}
35+
let _ = upsert_document().await;
36+
}

0 commit comments

Comments
 (0)