Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions source/crud/update/replace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,73 @@ and the immutable ``_id`` field as follows:
"quantity" : 107
}

Replace One Document Example: Full File
---------------------------------------

.. include:: /includes/usage-examples/example-intro.rst

This example performs the following actions on the ``restaurants``
collection:

- Matches a document in which the value of ``name`` is "Rizzo's Fine Pizza"
- Replaces the matched document with a new document

Select the **Struct** or **bson.D** tab to see the corresponding code:

.. tabs::

.. tab :: Struct
:tabid: structExample

The following code uses structs to replace a document, in which the value of
``name`` is "Rizzo's Fine Pizza", with a new document:

.. io-code-block::
:copyable: true

.. input:: /includes/usage-examples/code-snippets/replace.go
:language: go
:dedent:

.. output::
:language: none
:visible: false

Number of documents replaced: 1

.. tab :: bson.D
:tabid: bsonDExample

The following code uses a bson.D type to replace a document, in which the value of
``name`` is "Rizzo's Fine Pizza", with a new document:

.. io-code-block::
:copyable: true

.. input:: /includes/usage-examples/code-snippets/replaceBsonD.go
:language: go
:dedent:

.. output::
:language: none
:visible: false

Number of documents replaced: 1

Expected Result
~~~~~~~~~~~~~~~

After you run the full example, you can find the following replaced document
in the ``restaurants`` collection:

.. code-block:: none

{
"_id" : ObjectId("..."),
"name" : "Rizzo's Pizza",
"cuisine" : "Pizza/American"
}

API Documentation
-----------------

Expand Down
14 changes: 6 additions & 8 deletions source/includes/usage-examples/code-snippets/replace.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import (
"os"

"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)

// start-restaurant-struct
type Restaurant struct {
Name string
RestaurantId string `bson:"restaurant_id,omitempty"`
Expand All @@ -23,7 +21,9 @@ type Restaurant struct {
Grades []interface{} `bson:"grades,omitempty"`
}

// end-restaurant-struct
type RestaurantNameFilter struct {
Copy link
Member

Choose a reason for hiding this comment

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

Using a struct as a filter is quite awkward and error prone. For example, say you have the following filter struct:

type RNFilter struct {
	Name string 
	Rating int 
}

In Go, if you don't populate both fields then the filter will use the "zero" value for Rating:

f := RNFilter{Name: "Rizzo's Fine Pizza"} // Rating is implicitly 0

So if the actual rating is anything other than "0", nothing will be found since the underlying command is something of this shape:

{"name": "Rizzo's Fine Pizza", "rating": 0}

Suggest retaining bson.D for the filter. Using a go struct for decoding results into is best practice.

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 see, let me check in with @rishitb-mongodb .

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think @prestonvasquez 's thought makes sense. Let's standardize on defining the queries via bson.D (i.e for any filters) and using the struct to represent the documents (when inserting new documents or retrieving results).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, will do.

Name string
}

func main() {
if err := godotenv.Load(); err != nil {
Expand All @@ -45,23 +45,21 @@ func main() {
}
}()

// begin replace
coll := client.Database("sample_restaurants").Collection("restaurants")
filter := bson.D{{"name", "Madame Vo"}}
filter := RestaurantNameFilter{Name: "Rizzo's Fine Pizza"}
Copy link
Member

Choose a reason for hiding this comment

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

@lindseymoore Could you clarify the goal of this update? Is it to illustrate how users could use either a bson.D{} or Go struct as the filter argument for driver operations?

Copy link
Collaborator Author

@lindseymoore lindseymoore Jul 24, 2025

Choose a reason for hiding this comment

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

Hi, exactly! We received this ticket from the Go PM to add both bson.D and structs to the usage examples : https://jira.mongodb.org/browse/DOCSP-51595 @prestonvasquez


// Creates a new document containing "Name" and "Cuisine" fields
replacement := Restaurant{Name: "Monsieur Vo", Cuisine: "Asian Fusion"}
replacement := Restaurant{Name: "Rizzo's Pizza", Cuisine: "Pizza/American"}

// Replaces the first document that matches the filter with a new document
result, err := coll.ReplaceOne(context.TODO(), filter, replacement)
if err != nil {
panic(err)
}
// end replace

// Prints the number of modified documents
if result.MatchedCount != 0 {
fmt.Println("Number of documents replaced: %d\n", result.ModifiedCount)
fmt.Println("Number of documents replaced:", result.ModifiedCount)
}

// When you run this file for the first time, it should print:
Expand Down
58 changes: 58 additions & 0 deletions source/includes/usage-examples/code-snippets/replaceBsonD.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Replaces the first document that matches a filter by using the Go driver
package main

import (
"context"
"fmt"
"log"
"os"

"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)

func main() {
if err := godotenv.Load(); err != nil {
log.Println("No .env file found")
}

var uri string
if uri = os.Getenv("MONGODB_URI"); uri == "" {
log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable")
}

client, err := mongo.Connect(options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer func() {
if err = client.Disconnect(context.TODO()); err != nil {
panic(err)
}
}()

coll := client.Database("sample_restaurants").Collection("restaurants")
filter := bson.D{{"name", "Rizzo's Fine Pizza"}}

// Creates a new document containing "Name" and "Cuisine" fields
replacement := bson.D{
bson.E{Key: "name", Value: "Rizzo's Pizza"},
bson.E{Key: "cuisine", Value: "Pizza/American"},
}

// Replaces the first document that matches the filter with a new document
result, err := coll.ReplaceOne(context.TODO(), filter, replacement)
if err != nil {
panic(err)
}

// Prints the number of modified documents
if result.MatchedCount != 0 {
fmt.Println("Number of documents replaced:", result.ModifiedCount)
}

// When you run this file for the first time, it should print:
Copy link
Collaborator

Choose a reason for hiding this comment

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

[q] What do you think about removing vs keeping these comments at the end of the files? I think I've been removing since the output is shown in the code block but maybe we could align and make sure they're all consistent. I'm fine either way!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For this particular comment, I think it's good to keep in! If you run this code example twice, it outputs nothing the second time because the document that is being queried for no longer exists.
I also think it's nice to keep because readers will hopefully copy this into their own code editors, and they can have the expected result without referencing the docs again. I am in favor of keeping them in if this makes sense to you!

// Number of documents replaced: 1
}
Loading