Skip to content

Commit efe9cab

Browse files
RUST-1851 / RUST-1852 Bulk write sync API and documentation (#1107)
1 parent c4811ce commit efe9cab

File tree

4 files changed

+154
-11
lines changed

4 files changed

+154
-11
lines changed

src/action/bulk_write.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![allow(missing_docs)]
2-
31
use std::{collections::HashMap, marker::PhantomData};
42

53
use crate::{
@@ -12,9 +10,19 @@ use crate::{
1210
ClientSession,
1311
};
1412

15-
use super::{action_impl, option_setters};
13+
use super::{action_impl, deeplink, option_setters};
1614

1715
impl Client {
16+
/// Executes the provided list of write operations.
17+
///
18+
/// This operation will retry once upon failure if the connection and encountered error support
19+
/// retryability. See the documentation
20+
/// [here](https://www.mongodb.com/docs/manual/core/retryable-writes/) for more information on
21+
/// retryable writes.
22+
///
23+
/// `await` will return d[`Result<SummaryBulkWriteResult`] or d[`Result<VerboseBulkWriteResult`]
24+
/// if [`verbose_results`](BulkWrite::verbose_results) is configured.
25+
#[deeplink]
1826
pub fn bulk_write(
1927
&self,
2028
models: impl IntoIterator<Item = impl Into<WriteModel>>,
@@ -27,6 +35,28 @@ impl Client {
2735
}
2836
}
2937

38+
#[cfg(feature = "sync")]
39+
impl crate::sync::Client {
40+
/// Executes the provided list of write operations.
41+
///
42+
/// This operation will retry once upon failure if the connection and encountered error support
43+
/// retryability. See the documentation
44+
/// [here](https://www.mongodb.com/docs/manual/core/retryable-writes/) for more information on
45+
/// retryable writes.
46+
///
47+
/// [`run`](BulkWrite::run) will return d[`Result<SummaryBulkWriteResult`] or
48+
/// d[`Result<VerboseBulkWriteResult`] if [`verbose_results`](BulkWrite::verbose_results) is
49+
/// configured.
50+
#[deeplink]
51+
pub fn bulk_write(
52+
&self,
53+
models: impl IntoIterator<Item = impl Into<WriteModel>>,
54+
) -> BulkWrite<SummaryBulkWriteResult> {
55+
self.async_client.bulk_write(models)
56+
}
57+
}
58+
59+
/// Performs multiple write operations. Construct with [`Client::bulk_write`].
3060
#[must_use]
3161
pub struct BulkWrite<'a, R> {
3262
client: &'a Client,
@@ -37,6 +67,8 @@ pub struct BulkWrite<'a, R> {
3767
}
3868

3969
impl<'a> BulkWrite<'a, SummaryBulkWriteResult> {
70+
/// Return a [`VerboseBulkWriteResult`] with individual results for each successfully performed
71+
/// write.
4072
pub fn verbose_results(self) -> BulkWrite<'a, VerboseBulkWriteResult> {
4173
BulkWrite {
4274
client: self.client,
@@ -60,8 +92,9 @@ where
6092
write_concern: WriteConcern,
6193
);
6294

63-
pub fn session(mut self, session: &'a mut ClientSession) -> Self {
64-
self.session = Some(session);
95+
/// Use the provided session when running the operation.
96+
pub fn session(mut self, session: impl Into<&'a mut ClientSession>) -> Self {
97+
self.session = Some(session.into());
6598
self
6699
}
67100

src/client/options/bulk_write.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![allow(missing_docs)]
2-
31
use std::borrow::Borrow;
42

53
use serde::{Deserialize, Serialize};
@@ -16,25 +14,47 @@ use crate::{
1614
Namespace,
1715
};
1816

17+
/// The supported options for [`bulk_write`](crate::Client::bulk_write).
1918
#[skip_serializing_none]
2019
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
2120
#[serde(rename_all = "camelCase")]
2221
#[non_exhaustive]
2322
pub struct BulkWriteOptions {
23+
/// Whether the operations should be performed in the order in which they were specified. If
24+
/// true, no more writes will be performed if a single write fails. If false, writes will
25+
/// continue to be attempted if a single write fails.
26+
///
27+
/// Defaults to true.
2428
#[serialize_always]
2529
#[serde(serialize_with = "serialize_bool_or_true")]
2630
pub ordered: Option<bool>,
31+
32+
/// Whether document-level validation should be bypassed.
33+
///
34+
/// Defaults to false.
2735
pub bypass_document_validation: Option<bool>,
36+
37+
/// An arbitrary comment to help trace the operation through the database profiler, currentOp
38+
/// and logs.
2839
pub comment: Option<Bson>,
40+
41+
/// A map of parameter names and values to apply to all operations within the bulk write.
42+
/// Values must be constant or closed expressions that do not reference document fields.
43+
/// Parameters can then be accessed as variables in an aggregate expression context (e.g.
44+
/// "$$var").
2945
#[serde(rename = "let")]
3046
pub let_vars: Option<Document>,
47+
48+
/// The write concern to use for this operation.
3149
pub write_concern: Option<WriteConcern>,
3250
}
3351

52+
/// A single write to be performed within a [`bulk_write`](crate::Client::bulk_write) operation.
3453
#[skip_serializing_none]
3554
#[derive(Clone, Debug, Serialize)]
3655
#[serde(untagged)]
3756
#[non_exhaustive]
57+
#[allow(missing_docs)]
3858
pub enum WriteModel {
3959
InsertOne(InsertOneModel),
4060
UpdateOne(UpdateOneModel),
@@ -44,17 +64,20 @@ pub enum WriteModel {
4464
DeleteMany(DeleteManyModel),
4565
}
4666

67+
/// Inserts a single document.
4768
#[skip_serializing_none]
4869
#[derive(Clone, Debug, Serialize, TypedBuilder)]
4970
#[cfg_attr(test, derive(Deserialize))]
5071
#[serde(rename_all = "camelCase")]
5172
#[builder(field_defaults(default, setter(into)))]
5273
#[non_exhaustive]
5374
pub struct InsertOneModel {
75+
/// The namespace on which the insert should be performed.
5476
#[serde(skip_serializing)]
5577
#[builder(!default)]
5678
pub namespace: Namespace,
5779

80+
/// The document to insert.
5881
#[builder(!default)]
5982
pub document: Document,
6083
}
@@ -65,30 +88,41 @@ impl From<InsertOneModel> for WriteModel {
6588
}
6689
}
6790

91+
/// Updates a single document.
6892
#[skip_serializing_none]
6993
#[derive(Clone, Debug, Serialize, TypedBuilder)]
7094
#[cfg_attr(test, derive(Deserialize))]
7195
#[serde(rename_all = "camelCase")]
7296
#[builder(field_defaults(default, setter(into)))]
7397
#[non_exhaustive]
7498
pub struct UpdateOneModel {
99+
/// The namespace on which the update should be performed.
75100
#[serde(skip_serializing)]
76101
#[builder(!default)]
77102
pub namespace: Namespace,
78103

104+
/// The filter to use. The first document matching this filter will be updated.
79105
#[builder(!default)]
80106
pub filter: Document,
81107

108+
/// The update to perform.
82109
#[serde(rename(serialize = "updateMods"))]
83110
#[builder(!default)]
84111
pub update: UpdateModifications,
85112

113+
/// A set of filters specifying to which array elements an update should apply.
86114
pub array_filters: Option<Array>,
87115

116+
/// The collation to use.
88117
pub collation: Option<Document>,
89118

119+
/// The index to use. Specify either the index name as a string or the index key pattern. If
120+
/// specified, then the query system will only consider plans using the hinted index.
90121
pub hint: Option<Bson>,
91122

123+
/// Whether a new document should be created if no document matches the filter.
124+
///
125+
/// Defaults to false.
92126
pub upsert: Option<bool>,
93127
}
94128

@@ -98,30 +132,41 @@ impl From<UpdateOneModel> for WriteModel {
98132
}
99133
}
100134

135+
/// Updates multiple documents.
101136
#[skip_serializing_none]
102137
#[derive(Clone, Debug, Serialize, TypedBuilder)]
103138
#[cfg_attr(test, derive(Deserialize))]
104139
#[serde(rename_all = "camelCase")]
105140
#[builder(field_defaults(default, setter(into)))]
106141
#[non_exhaustive]
107142
pub struct UpdateManyModel {
143+
/// The namespace on which the update should be performed.
108144
#[serde(skip_serializing)]
109145
#[builder(!default)]
110146
pub namespace: Namespace,
111147

148+
/// The filter to use. All documents matching this filter will be updated.
112149
#[builder(!default)]
113150
pub filter: Document,
114151

152+
/// The update to perform.
115153
#[serde(rename(serialize = "updateMods"))]
116154
#[builder(!default)]
117155
pub update: UpdateModifications,
118156

157+
/// A set of filters specifying to which array elements an update should apply.
119158
pub array_filters: Option<Array>,
120159

160+
/// The collation to use.
121161
pub collation: Option<Document>,
122162

163+
/// The index to use. Specify either the index name as a string or the index key pattern. If
164+
/// specified, then the query system will only consider plans using the hinted index.
123165
pub hint: Option<Bson>,
124166

167+
/// Whether a new document should be created if no document matches the filter.
168+
///
169+
/// Defaults to false.
125170
pub upsert: Option<bool>,
126171
}
127172

@@ -131,28 +176,38 @@ impl From<UpdateManyModel> for WriteModel {
131176
}
132177
}
133178

179+
/// Replaces a single document.
134180
#[skip_serializing_none]
135181
#[derive(Clone, Debug, Serialize, TypedBuilder)]
136182
#[cfg_attr(test, derive(Deserialize))]
137183
#[serde(rename_all = "camelCase")]
138184
#[builder(field_defaults(default, setter(into)))]
139185
#[non_exhaustive]
140186
pub struct ReplaceOneModel {
187+
/// The namespace on which the replace should be performed.
141188
#[serde(skip_serializing)]
142189
#[builder(!default)]
143190
pub namespace: Namespace,
144191

192+
/// The filter to use.
145193
#[builder(!default)]
146194
pub filter: Document,
147195

196+
/// The replacement document.
148197
#[serde(rename(serialize = "updateMods"))]
149198
#[builder(!default)]
150199
pub replacement: Document,
151200

201+
/// The collation to use.
152202
pub collation: Option<Document>,
153203

204+
/// The index to use. Specify either the index name as a string or the index key pattern. If
205+
/// specified, then the query system will only consider plans using the hinted index.
154206
pub hint: Option<Bson>,
155207

208+
/// Whether a new document should be created if no document matches the filter.
209+
///
210+
/// Defaults to false.
156211
pub upsert: Option<bool>,
157212
}
158213

@@ -162,22 +217,28 @@ impl From<ReplaceOneModel> for WriteModel {
162217
}
163218
}
164219

220+
/// Deletes a single document.
165221
#[skip_serializing_none]
166222
#[derive(Clone, Debug, Serialize, TypedBuilder)]
167223
#[cfg_attr(test, derive(Deserialize))]
168224
#[serde(rename_all = "camelCase")]
169225
#[builder(field_defaults(default, setter(into)))]
170226
#[non_exhaustive]
171227
pub struct DeleteOneModel {
228+
/// The namespace on which the delete should be performed.
172229
#[serde(skip_serializing)]
173230
#[builder(!default)]
174231
pub namespace: Namespace,
175232

233+
/// The filter to use. The first document matching this filter will be deleted.
176234
#[builder(!default)]
177235
pub filter: Document,
178236

237+
/// The collation to use.
179238
pub collation: Option<Document>,
180239

240+
/// The index to use. Specify either the index name as a string or the index key pattern. If
241+
/// specified, then the query system will only consider plans using the hinted index.
181242
pub hint: Option<Bson>,
182243
}
183244

@@ -187,21 +248,27 @@ impl From<DeleteOneModel> for WriteModel {
187248
}
188249
}
189250

251+
/// Deletes multiple documents.
190252
#[skip_serializing_none]
191253
#[derive(Clone, Debug, Serialize, TypedBuilder)]
192254
#[cfg_attr(test, derive(Deserialize))]
193255
#[serde(rename_all = "camelCase")]
194256
#[builder(field_defaults(default, setter(into)))]
195257
#[non_exhaustive]
196258
pub struct DeleteManyModel {
259+
/// The namespace on which the delete should be performed.
197260
#[serde(skip_serializing)]
198261
#[builder(!default)]
199262
pub namespace: Namespace,
200263

264+
/// The filter to use. All documents matching this filter will be deleted.
201265
pub filter: Document,
202266

267+
/// The collation to use.
203268
pub collation: Option<Document>,
204269

270+
/// The index to use. Specify either the index name as a string or the index key pattern. If
271+
/// specified, then the query system will only consider plans using the hinted index.
205272
pub hint: Option<Bson>,
206273
}
207274

@@ -215,6 +282,11 @@ impl<T> Collection<T>
215282
where
216283
T: Send + Sync + Serialize,
217284
{
285+
/// Constructs an [`InsertOneModel`] with this collection's namespace by serializing the
286+
/// provided value into a [`Document`]. Returns an error if serialization fails.
287+
///
288+
/// Note that the returned value must be provided to [`bulk_write`](crate::Client::bulk_write)
289+
/// for the insert to be performed.
218290
pub fn insert_one_model(&self, document: impl Borrow<T>) -> Result<InsertOneModel> {
219291
let document = bson::to_document(document.borrow())?;
220292
Ok(InsertOneModel::builder()
@@ -223,6 +295,11 @@ where
223295
.build())
224296
}
225297

298+
/// Constructs a [`ReplaceOneModel`] with this collection's namespace by serializing the
299+
/// provided value into a [`Document`]. Returns an error if serialization fails.
300+
///
301+
/// Note that the returned value must be provided to [`bulk_write`](crate::Client::bulk_write)
302+
/// for the replace to be performed.
226303
pub fn replace_one_model(
227304
&self,
228305
filter: Document,

0 commit comments

Comments
 (0)