Skip to content

Commit 87d6b12

Browse files
DOCSP-13844 crud upsert (#71)
* added CRUD upsert page
1 parent 663580e commit 87d6b12

File tree

3 files changed

+172
-7
lines changed

3 files changed

+172
-7
lines changed

source/fundamentals/crud/write-operations.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ Write Operations
77
- :doc:`/fundamentals/crud/write-operations/insert`
88
- :doc:`/fundamentals/crud/write-operations/delete`
99
- :doc:`/fundamentals/crud/write-operations/change-a-document`
10+
- :doc:`/fundamentals/crud/write-operations/upsert`
1011

1112
..
12-
- :doc:`/fundamentals/crud/write-operations/upsert`
1313
- :doc:`/fundamentals/crud/write-operations/embedded-arrays`
1414

1515
.. toctree::
@@ -18,7 +18,7 @@ Write Operations
1818
/fundamentals/crud/write-operations/insert
1919
/fundamentals/crud/write-operations/delete
2020
/fundamentals/crud/write-operations/change-a-document
21+
/fundamentals/crud/write-operations/upsert
2122

2223
..
23-
/fundamentals/crud/write-operations/upsert
2424
/fundamentals/crud/write-operations/embedded-arrays

source/fundamentals/crud/write-operations/upsert.txt

Lines changed: 107 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,110 @@ Insert or Update in a Single Operation
44

55
.. default-domain:: mongodb
66

7-
If your application stores and modifies data in MongoDB, you probably use
8-
insert and update operations. In certain workflows, you may need to choose
9-
between an insert and update depending on whether the document exists.
10-
In these cases, you can streamline your application logic by using the
11-
``upsert`` option available in the following methods:
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
.. _upsert_golang:
14+
15+
Overview
16+
--------
17+
18+
In this guide, you can learn how to specify an :ref:`upsert
19+
<upsert-definition-go>`.
20+
21+
Sample Data
22+
~~~~~~~~~~~
23+
24+
To run the example in this guide, load the sample data into the
25+
``ratings`` collection of the ``tea`` database with the following
26+
snippet:
27+
28+
.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/upsert.go
29+
:language: go
30+
:dedent:
31+
:start-after: begin insert docs
32+
:end-before: end insert docs
33+
34+
.. include:: /includes/fundamentals/automatic-db-coll-creation.rst
35+
36+
Each document contains a rating for a type of tea that corresponds to
37+
the ``type`` and ``rating`` fields.
38+
39+
Upsert
40+
------
41+
42+
Applications use insert and update operations to store and modify data.
43+
Sometimes, you need to choose between an insert and an update operation
44+
depending on whether the document exists. MongoDB simplifies this
45+
decision for us with an **upsert** option.
46+
47+
.. _upsert-definition-go:
48+
49+
An upsert performs one of the following actions:
50+
51+
- Update documents that match your query filter
52+
- Insert a document if there are no matches to your query filter
53+
54+
You can specify an upsert by passing ``true`` to the ``SetUpsert()``
55+
function in the options of the following write operation functions:
56+
57+
- ``UpdateOne()``
58+
- ``UpdateByID()``
59+
- ``UpdateMany()``
60+
- ``ReplaceOne()``
61+
- ``FindOneAndUpdate()``
62+
- ``FindOneAndReplace()``
63+
64+
.. tip::
65+
66+
If you don't specify an upsert, no change occurs in the write
67+
operation when zero documents match your query filter. This is
68+
equivalent to passing ``false`` to the ``SetUpsert()`` function.
69+
70+
Example
71+
~~~~~~~
72+
73+
The following example performs the following actions:
74+
75+
- Matches documents where the ``type`` is "Oolong"
76+
- Updates the ``rating`` of the matched document to ``8``
77+
- Inserts this document if there are no matches to your query filter
78+
79+
.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/upsert.go
80+
:language: go
81+
:dedent:
82+
:start-after: begin upsert
83+
:end-before: end upsert
84+
85+
The expected output of this example is as follows:
86+
87+
.. code-block:: none
88+
:copyable: false
89+
90+
Number of documents updated: 0
91+
Number of documents upserted: 1
92+
93+
Additional Information
94+
----------------------
95+
96+
For information on how to update or replace documents, see the guide on
97+
:doc:`Changing a Document </fundamentals/crud/write-operations/change-a-document>`.
98+
99+
API Documentation
100+
~~~~~~~~~~~~~~~~~
101+
102+
For more information on any of the functions or types mentioned in this
103+
guide, see the following API Documentation:
104+
105+
- `UpdateOne() <{+api+}/mongo#Collection.UpdateOne>`__
106+
- `UpdateByID() <{+api+}/mongo#Collection.UpdateByID>`__
107+
- `UpdateMany() <{+api+}/mongo#Collection.UpdateMany>`__
108+
- `ReplaceOne() <{+api+}/mongo#Collection.ReplaceOne>`__
109+
- `FindOneAndUpdate() <{+api+}/mongo#Collection.FindOneAndUpdate>`__
110+
- `FindOneAndReplace() <{+api+}/mongo#Collection.FindOneAndReplace>`__
111+
- `UpdateOptions.SetUpsert() <{+api+}/mongo/options#UpdateOptions.SetUpsert>`__
112+
- `ReplaceOptions.SetUpsert() <{+api+}/mongo/options#ReplaceOptions.SetUpsert>`__
113+
- `UpdateResult <{+api+}/mongo#UpdateResult>`__
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"os"
8+
9+
"go.mongodb.org/mongo-driver/bson"
10+
"go.mongodb.org/mongo-driver/mongo"
11+
"go.mongodb.org/mongo-driver/mongo/options"
12+
)
13+
14+
func main() {
15+
var uri string
16+
if uri = os.Getenv("MONGODB_URI"); uri == "" {
17+
log.Fatal("You must set your 'MONGODB_URI' environmental variable. See\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/")
18+
}
19+
20+
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
21+
22+
if err != nil {
23+
panic(err)
24+
}
25+
defer func() {
26+
if err = client.Disconnect(context.TODO()); err != nil {
27+
panic(err)
28+
}
29+
}()
30+
31+
client.Database("tea").Collection("ratings").Drop(context.TODO())
32+
33+
// begin insert docs
34+
coll := client.Database("tea").Collection("ratings")
35+
docs := []interface{}{
36+
bson.D{{"type", "Masala"}, {"rating", 10}},
37+
bson.D{{"type", "Assam"}, {"rating", 5}},
38+
}
39+
40+
result, err := coll.InsertMany(context.TODO(), docs)
41+
if err != nil {
42+
panic(err)
43+
}
44+
fmt.Printf("Number of documents inserted: %d\n", len(result.InsertedIDs))
45+
//end insert docs
46+
47+
fmt.Println("Upsert:")
48+
{
49+
// begin upsert
50+
filter := bson.D{{"type", "Oolong"}}
51+
update := bson.D{{"$set", bson.D{{"rating", 8}}}}
52+
opts := options.Update().SetUpsert(true)
53+
54+
result, err := coll.UpdateOne(context.TODO(), filter, update, opts)
55+
if err != nil {
56+
panic(err)
57+
}
58+
59+
fmt.Printf("Number of documents updated: %v\n", result.ModifiedCount)
60+
fmt.Printf("Number of documents upserted: %v\n", result.UpsertedCount)
61+
// end upsert
62+
}
63+
}

0 commit comments

Comments
 (0)