Skip to content

DOCSP-39895: Bulk write guide #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jun 11, 2024

Conversation

norareidy
Copy link
Collaborator

@norareidy norareidy commented May 28, 2024

Pull Request Info

PR Reviewing Guidelines

JIRA - https://jira.mongodb.org/browse/DOCSP-39895
Staging - https://preview-mongodbnorareidy.gatsbyjs.io/rust/DOCSP-39895-bulk-write-guide/fundamentals/crud/write-operations/bulk/

Self-Review Checklist

  • Is this free of any warnings or errors in the RST?
  • Did you run a spell-check?
  • Did you run a grammar-check?
  • Are all the links working?
  • Are the facets and meta keywords accurate?

Copy link
Collaborator

@rustagir rustagir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work so far! Lmk if you have any questions about my feedback.

Overview
--------

In this guide, you can learn how to use **bulk operations**.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this guide, you can learn how to use **bulk operations**.
In this guide, you can learn how to perform **bulk operations**.

In this guide, you can learn how to use **bulk operations**.

Bulk operations perform multiple write operations against one or more
namespaces. Instead of making a call to the database for each operation,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: since you are introducing the namespace terminology, add a clause or sentence explaining what that means

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also indicate that the bulk_write() method is in the Client class, which enables this feature against any namespace in the cluster


Bulk operations perform multiple write operations against one or more
namespaces. Instead of making a call to the database for each operation,
bulk operations perform multiple operations with one database call.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bulk operations perform multiple operations with one database call.
bulk operations perform multiple operations within one call to the database.

Comment on lines 24 to 28
- :ref:`bulk-sample-data`
- :ref:`bulk-operation-types`
- :ref:`bulk-modify-behavior`
- :ref:`bulk-mixed-namespaces`
- :ref:`bulk-addtl-info`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: for multi-repo crosslinking and organization, make sure all anchors contain rust

Comment on lines 32 to 36
To perform bulk write operations, ensure that your application meets the
following requirements:

- You are connected to MongoDB Server version 8.0 or later.
- You are using {+driver-short+} version 3.0 or later.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: indentation

Comment on lines 218 to 220
- | The filter that matches one or more documents you want to update. When specified in an ``UpdateOneModel``,
| only the first matching document will be updated. When specified in an ``UpdateManyModel``, all
| matching documents will be updated.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I: remove the newline breaks | from the beginning of each line in the paragraph

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applies everywhere you might have done this

| Type: ``UpdateModifications``

* - ``array_filters``
- | (Optional) A set of filters specifying which array elements an update applies to.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- | (Optional) A set of filters specifying which array elements an update applies to.
- | (Optional) A set of filters specifying which array elements an update applies to if you are updating an array-valued field.

let insert_many_result = mushrooms.insert_many(docs, None).await?;

// begin-insert
let mushrooms: Collection<Mushroom> = client.database("db").collection("mushrooms");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: reduce horizontal scroll (applies to all)

Suggested change
let mushrooms: Collection<Mushroom> = client.database("db").collection("mushrooms");
let mushrooms: Collection<Mushroom> = client
.database("db")
.collection("mushrooms");

@norareidy norareidy requested a review from rustagir June 4, 2024 20:43
Copy link
Collaborator

@rustagir rustagir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more things but good work!

Overview
--------

In this guide, you can learn how to perform **bulk operations**.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this guide, you can learn how to perform **bulk operations**.
In this guide, you can learn how to use the {+driver-short+} to perform **bulk operations**.

Comment on lines 18 to 22
Bulk operations perform multiple write operations against one or more
namespaces, which refer to a database name and a collection name in
``<database>.<collection>`` form. Since the bulk operation method is in
the ``Client`` class, you can perform bulk operations against any namespace
in your cluster.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S; use wording from the Server glossary

Suggested change
Bulk operations perform multiple write operations against one or more
namespaces, which refer to a database name and a collection name in
``<database>.<collection>`` form. Since the bulk operation method is in
the ``Client`` class, you can perform bulk operations against any namespace
in your cluster.
Bulk operations perform multiple write operations against one or more
**namespaces**. A namespace is a combination of the database name and the collection name, in the format
``<database>.<collection>``. Since you perform bulk operations on a
the ``Client`` instance, you can perform bulk operations against any namespace
in the cluster accessed by your client.

Comment on lines 24 to 25
Instead of making a call to the database for each operation, bulk operations
perform multiple operations within one call to the database.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: right now, this sentence seems a little isolated, maybe you can make this a description of why one might use bulk ops.

Suggested change
Instead of making a call to the database for each operation, bulk operations
perform multiple operations within one call to the database.
You might perform a bulk operation to reduce the number of calls to the server. Instead of sending
a request for each operation, bulk operations perform multiple operations within one action.

@norareidy norareidy requested a review from rustagir June 5, 2024 20:27
Copy link
Collaborator

@rustagir rustagir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with a few last comments! great work documenting this APi!

To perform a bulk insert operation, create an ``InsertOneModel`` instance for each document
you want to insert. Then, pass a list of models to the ``bulk_write()`` method.

To construct an ``InsertOneModel``, specify the following struct fields:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: introduce this table (and in other sections) by clarifying that you set these fields by using the corresponding builder methods.

Comment on lines 399 to 400
The following example sets the ``ordered`` field to ``false`` by chaining the ``ordered()`` method
to the ``bulk_write()`` method:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following example sets the ``ordered`` field to ``false`` by chaining the ``ordered()`` method
to the ``bulk_write()`` method:
The following example attempts to perform update and insert operations on the ``mushrooms`` collection
and sets the ``ordered`` field to ``false`` by chaining the ``ordered()`` method
to the ``bulk_write()`` method:

Comment on lines 421 to 424
The ``_id`` field is immutable and cannot be changed in an update operation. Since the ``UpdateOneModel``
includes instructions to update this field, the bulk operation generates a ``BulkWriteError`` and performs
only an insert operation. If you do not set the ``ordered`` field to ``false``, the bulk operation will not
attempt any subsequent operations after the unsuccessful update and will not insert the specified document.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The ``_id`` field is immutable and cannot be changed in an update operation. Since the ``UpdateOneModel``
includes instructions to update this field, the bulk operation generates a ``BulkWriteError`` and performs
only an insert operation. If you do not set the ``ordered`` field to ``false``, the bulk operation will not
attempt any subsequent operations after the unsuccessful update and will not insert the specified document.
The ``_id`` field is immutable and cannot be changed in an update operation. Since the ``UpdateOneModel``
includes instructions to update this field, the bulk operation returns a ``BulkWriteError`` and performs
only the insert operation. If you set the ``ordered`` field to ``true``, the driver does not
attempt any subsequent operations after the unsuccessful update operation, and the driver does not insert any documents.

Copy link
Collaborator

@isabelatkinson isabelatkinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just a few suggestions. Also recommend considering adding a section about generating verbose results using this action method.

Bulk Operation Types
--------------------

To perform a bulk write operation, pass an array of ``WriteModel`` struct instances to the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To perform a bulk write operation, pass an array of ``WriteModel`` struct instances to the
To perform a bulk write operation, pass an array of ``WriteModel`` enum instances to the

Comment on lines 371 to 372
| When set to ``true``, the driver does not perform subsequent write operations if one operation fails.
| When set to ``false``, the driver continues to attempt write operations if one fails.
Copy link
Collaborator

@isabelatkinson isabelatkinson Jun 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor, but the actual continue-on-error behavior is done by the server, not the driver (for the most part). I'd remove mention of the driver here.

);
// end-options

// begin-mixed-namespaces
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you whether this would be worth the additional text, but this could be a good spot to make the collections generic over a non-Document type and demonstrate how to use this helper method.

e.g.

#[derive(Serialize)]
struct Sweet {
    name: String,
    price: f32,
}

let sweets: Collection<Sweet> = client.database("ingredients").collection("sweets");
let sweet = Sweet {
    name: "brown sugar".to_string(),
    price: 3.99,
};
let insert_sweet_model = sweets.insert_one_model(sweet)?;

// ditto for dessert

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a section to Insert Operations instead that uses a Mushroom struct and insert_one_model()!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also added a section on bulk write return values, which includes a verbose_results() explanation

@rustagir rustagir self-requested a review June 10, 2024 19:43
Copy link
Collaborator

@rustagir rustagir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things, re-request if needed!

Comment on lines 66 to 68
You can also use custom struct types to represent your sample data. For
an example that performs a bulk operation using the ``Mushroom`` struct type,
see the :ref:`bulk-insert-structs-example` on this page.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can also use custom struct types to represent your sample data. For
an example that performs a bulk operation using the ``Mushroom`` struct type,
see the :ref:`bulk-insert-structs-example` on this page.
You can also use custom struct types to represent your sample data. For
an example that performs a bulk operation by using ``Mushroom`` structs to model the same data,
see the :ref:`bulk-insert-structs-example` on this page.

Insert Structs Example
``````````````````````

You can also model your documents as structs and insert them into the ``db.mushrooms`` namespace.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can also model your documents as structs and insert them into the ``db.mushrooms`` namespace.
You can also model your documents by using structs and bulk insert struct instances
into the ``db.mushrooms`` namespace.

Comment on lines 161 to 162
The following code uses the ``insert_one_model()`` method to construct an ``InsertOneModel``
from each ``Mushroom`` instance:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following code uses the ``insert_one_model()`` method to construct an ``InsertOneModel``
from each ``Mushroom`` instance:
The following code uses the ``insert_one_model()`` method to construct an ``InsertOneModel``
from each ``Mushroom`` instance, then inserts both models in a bulk operation:

Comment on lines 398 to 399
See Bulk Write Results
----------------------
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See Bulk Write Results
----------------------
Return Type
------------

- ``upserted_count``: the number of upserted documents
- ``deleted_count``: the number of deleted documents

You can also use the ``verbose_results()`` method to see more detailed information about each
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can also use the ``verbose_results()`` method to see more detailed information about each
You can also use the ``verbose_results()`` method to see detailed information about each

Comment on lines 436 to 437
SummaryBulkWriteResult { inserted_count: 0, matched_count: 1, modified_count: 1,
upserted_count: 0, deleted_count: 1 }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: if this example uses the verbose_results() method, why is it printing a SummaryBulkWriteResult instead of a VerboseBulkWriteResult result?

Copy link
Collaborator Author

@norareidy norareidy Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verbose_results() returns a VerboseBulkWriteResult, but the summary field of the VerboseBulkWriteResult (which is what I'm printing) has a value of SummaryBulkWriteResult. Kinda confusing, here's the struct and its fields in the source code.

Copy link
Collaborator Author

@norareidy norareidy Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this ends up giving you the same information as omitting the verbose_results() call, I changed it to print the update_results and delete_results fields instead

@@ -149,7 +201,7 @@ async fn main() -> mongodb::error::Result<()> {
.build()),
];

let result = client.bulk_write(models).ordered(false).await?;
let result = client.bulk_write(models).ordered(false).verbose_results().await?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: why use verbose_results() here when the operation results in an error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, didn't mean to add this here - removed

@norareidy norareidy requested a review from isabelatkinson June 10, 2024 20:43
Copy link
Collaborator

@isabelatkinson isabelatkinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great!

@norareidy norareidy merged commit 673e0b6 into mongodb:master Jun 11, 2024
1 of 2 checks passed
@norareidy norareidy deleted the DOCSP-39895-bulk-write-guide branch June 11, 2024 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants