Skip to main content

entelix_memory_qdrant/
lib.rs

1//! # entelix-memory-qdrant
2//!
3//! Concrete [`entelix_memory::VectorStore`] implementation backed by
4//! the qdrant 1.5+ gRPC API.
5//!
6//! Companion to the trait-only [`entelix_memory`] crate:
7//! vendor-SDK dependencies (`qdrant-client` plus its tonic / prost
8//! transitive tree) live here so users who plug their own
9//! `VectorStore` pay nothing in compile time.
10//!
11//! ## One-call setup
12//!
13//! ```ignore
14//! use entelix_memory_qdrant::{DistanceMetric, QdrantVectorStore};
15//!
16//! let store = QdrantVectorStore::builder("memories", 1536)
17//!     .with_url("http://localhost:6334")
18//!     .with_distance(DistanceMetric::Cosine)
19//!     .build()
20//!     .await?;
21//! ```
22//!
23//! ## Multi-tenancy
24//!
25//! Single-collection design (qdrant official multi-tenancy
26//! guidance): every read / write / count / list rides a `must`
27//! anchor on the rendered [`entelix_memory::Namespace`]. Two
28//! tenants sharing the same operator-facing `doc_id` are stored as
29//! distinct points without coordination — the qdrant `PointId` is
30//! a deterministic UUID v5 of `(namespace_key, doc_id)`. The
31//! original `doc_id` survives in the payload for round-trip.
32//!
33//! ## Schema-as-code escape hatch
34//!
35//! Operators that provision the qdrant collection externally
36//! (helm chart, Terraform, qdrant Cloud console) call
37//! [`QdrantVectorStoreBuilder::with_existing_collection`] — the
38//! builder skips both collection creation and payload-index
39//! provisioning and trusts the operator to have stamped them.
40
41#![cfg_attr(docsrs, feature(doc_cfg))]
42#![doc(html_root_url = "https://docs.rs/entelix-memory-qdrant/0.5.3")]
43#![deny(missing_docs)]
44// `qdrant`, `Postgres`, etc. ride through doc strings as vendor names
45// (not code identifiers); backticking each occurrence is noise.
46// `Err`-variant size is large because `QdrantStoreError::Sqlx` boxes
47// the upstream chain — that's the point of `#[from]` and we accept
48// the heap-shaped Result on these cold paths.
49// `pub(crate)` items inside private modules are the canonical
50// crate-internal helper pattern.
51#![allow(
52    clippy::doc_markdown,
53    clippy::too_long_first_doc_paragraph,
54    clippy::result_large_err,
55    clippy::pub_with_shorthand,
56    clippy::redundant_pub_crate,
57    clippy::cast_precision_loss,
58    clippy::cast_possible_truncation,
59    clippy::cast_sign_loss,
60    clippy::cast_possible_wrap,
61    clippy::redundant_closure_for_method_calls,
62    clippy::needless_pass_by_value,
63    clippy::map_unwrap_or,
64    clippy::indexing_slicing,
65    clippy::expect_used
66)]
67
68mod error;
69mod filter;
70mod store;
71
72pub use error::{QdrantStoreError, QdrantStoreResult};
73pub use filter::{CONTENT_KEY, DOC_ID_KEY, METADATA_KEY, NAMESPACE_KEY};
74pub use store::{DistanceMetric, QdrantVectorStore, QdrantVectorStoreBuilder};