Skip to main content

mongodb/action/
count.rs

1use crate::bson::{Bson, Document};
2use std::time::Duration;
3
4use crate::{
5    coll::options::{CountOptions, EstimatedDocumentCountOptions, Hint},
6    collation::Collation,
7    concern::ReadConcern,
8    error::Result,
9    selection_criteria::SelectionCriteria,
10    ClientSession,
11    Collection,
12};
13
14use super::{action_impl, deeplink, export_doc, option_setters, options_doc, CollRef};
15
16impl<T> Collection<T>
17where
18    T: Send + Sync,
19{
20    /// Estimates the number of documents in the collection using collection metadata.
21    ///
22    /// Due to an oversight in versions 5.0.0 - 5.0.7 of MongoDB, the `count` server command,
23    /// which `estimatedDocumentCount` uses in its implementation, was not included in v1 of the
24    /// Stable API. Users of the Stable API with `estimatedDocumentCount` are recommended to
25    /// upgrade their cluster to 5.0.8+ or set
26    /// [`ServerApi::strict`](crate::options::ServerApi::strict) to false to avoid encountering
27    /// errors.
28    ///
29    /// For more information on the behavior of the `count` server command, see
30    /// [Count: Behavior](https://www.mongodb.com/docs/manual/reference/command/count/#behavior).
31    ///
32    /// `await` will return d[`Result<u64>`].
33    #[deeplink]
34    #[options_doc(estimated_doc_count)]
35    pub fn estimated_document_count(&self) -> EstimatedDocumentCount<'_> {
36        EstimatedDocumentCount {
37            cr: CollRef::new(self),
38            options: None,
39        }
40    }
41
42    /// Gets the number of documents. This method returns an accurate count.
43    ///
44    /// Certain query operators cannot be used in the filter provided to this method, including
45    /// `$where` and `$near`. See the documentation for the `$match` aggregation pipeline stage for
46    /// full details on these restrictions:
47    /// https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/#restrictions
48    ///
49    /// `await` will return d[`Result<u64>`].
50    #[deeplink]
51    #[options_doc(count_docs)]
52    pub fn count_documents(&self, filter: Document) -> CountDocuments<'_> {
53        CountDocuments {
54            cr: CollRef::new(self),
55            filter,
56            options: None,
57            session: None,
58        }
59    }
60}
61
62#[cfg(feature = "sync")]
63impl<T> crate::sync::Collection<T>
64where
65    T: Send + Sync,
66{
67    /// Estimates the number of documents in the collection using collection metadata.
68    ///
69    /// Due to an oversight in versions 5.0.0 - 5.0.7 of MongoDB, the `count` server command,
70    /// which `estimatedDocumentCount` uses in its implementation, was not included in v1 of the
71    /// Stable API. Users of the Stable API with `estimatedDocumentCount` are recommended to
72    /// upgrade their cluster to 5.0.8+ or set
73    /// [`ServerApi::strict`](crate::options::ServerApi::strict) to false to avoid encountering
74    /// errors.
75    ///
76    /// For more information on the behavior of the `count` server command, see
77    /// [Count: Behavior](https://www.mongodb.com/docs/manual/reference/command/count/#behavior).
78    ///
79    /// [`run`](EstimatedDocumentCount::run) will return d[`Result<u64>`].
80    #[deeplink]
81    #[options_doc(estimated_doc_count, "run")]
82    pub fn estimated_document_count(&self) -> EstimatedDocumentCount<'_> {
83        self.async_collection.estimated_document_count()
84    }
85
86    /// Gets the number of documents.
87    ///
88    /// Note that this method returns an accurate count.
89    ///
90    /// [`run`](CountDocuments::run) will return d[`Result<u64>`].
91    #[deeplink]
92    #[options_doc(count_docs, "run")]
93    pub fn count_documents(&self, filter: Document) -> CountDocuments<'_> {
94        self.async_collection.count_documents(filter)
95    }
96}
97
98/// Gather an estimated document count.  Construct with [`Collection::estimated_document_count`].
99#[must_use]
100pub struct EstimatedDocumentCount<'a> {
101    cr: CollRef<'a>,
102    options: Option<EstimatedDocumentCountOptions>,
103}
104
105#[option_setters(crate::coll::options::EstimatedDocumentCountOptions)]
106#[export_doc(estimated_doc_count)]
107impl EstimatedDocumentCount<'_> {}
108
109#[action_impl]
110impl<'a> Action for EstimatedDocumentCount<'a> {
111    type Future = EstimatedDocumentCountFuture;
112
113    async fn execute(mut self) -> Result<u64> {
114        let op = crate::operation::count::Count::new(self.cr.clone(), self.options);
115        self.cr.client().execute_operation(op, None).await
116    }
117}
118
119/// Get an accurate count of documents.  Construct with [`Collection::count_documents`].
120#[must_use]
121pub struct CountDocuments<'a> {
122    cr: CollRef<'a>,
123    filter: Document,
124    options: Option<CountOptions>,
125    session: Option<&'a mut ClientSession>,
126}
127
128#[option_setters(crate::coll::options::CountOptions)]
129#[export_doc(count_docs)]
130impl<'a> CountDocuments<'a> {
131    /// Use the provided session when running the operation.
132    pub fn session(mut self, value: impl Into<&'a mut ClientSession>) -> Self {
133        self.session = Some(value.into());
134        self
135    }
136}
137
138#[action_impl]
139impl<'a> Action for CountDocuments<'a> {
140    type Future = CountDocumentsFuture;
141
142    async fn execute(mut self) -> Result<u64> {
143        let op = crate::operation::count_documents::CountDocuments::new(
144            self.cr.inner(),
145            self.filter,
146            self.options,
147        )?;
148        self.cr.client().execute_operation(op, self.session).await
149    }
150}