Contents

Golang & MongoDB Query Cheat Sheet

MongoDB & Golang Query Examples - Cheat Sheet

This cheat sheet should help you about the MongoDB queries with Golang. We will start with some basic examples to more complex queries with Go Programming Language.

The examples are written with Go 1.19 and go.mongodb.org/mongo-driver/mongo.

Table Of Contents

Connecting to MongoDB

Inserting A Document to MongoDB

Writing Multiple Documents To MongoDB

Finding Single Document From MongoDB

Finding All Documents From MongoDB

Updating Document(s) From MongoDB

Deleting Document(s) From MongoDB

How to Connect to MongoDB with Golang

Connecting to MongoDB is fairly simple, you just connect the uri generated by the MongoDB.

Then we can use the client.Database() function to make sure that we are connecting to the correct database.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

	// disconnect the mongo client when main is completed
	defer func() {
		if err = client.Disconnect(ctx); err != nil {
			panic(err)
		}
	}()
}

To really make sure that we are connected to the correct database, we can use the Ping method.

1
2
3
ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
err = client.Ping(ctx, readpref.Primary())

Inserting A Document to MongoDB with Golang

To insert a document to MongoDB, we can use the bson.D provided by the MongoDB. But to make the operations more simple and more realistic to real world applications, we will use structs with bson tags.

The model we are using is

1
2
3
4
5
6
type Car struct {
	Id    primitive.ObjectID `bson:"_id"`
	Brand string             `bson:"brand"`
	Model string             `bson:"model"`
	Year  int                `bson:"year"`
}

Then we can simply use the InsertOne() method to insert a document to MongoDB.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
	Id        primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
	Brand     string             `bson:"brand"`
	Model     string             `bson:"model"`
	Year      int                `bson:"year"`
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

	exampleData := Car{
		Id:    primitive.NewObjectID(),
        CreatedAt: time.Now().UTC(),
		Brand: "Mercedes",
		Model: "G-360",
		Year:  2002,
	}

	res, err := db.Collection("cars").InsertOne(context.Background(), exampleData)
	if err != nil {
		log.Fatal(err)
	}

	// inserted id is ObjectID("639b62ae2518fbd9315e405d")
	log.Printf("inserted id is %v", res.InsertedID)
}

Writing Multiple Documents To MongoDB with Golang

We can use the InsertMany() method of the Collection object. However, the InsertMany() requires an []interface{} to work on.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
	Id        primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
	Brand     string             `bson:"brand"`
	Model     string             `bson:"model"`
	Year      int                `bson:"year"`
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

	var data []interface{}
	data = append(data, Car{
		Id:    primitive.NewObjectID(),
        CreatedAt: time.Now().UTC(),
		Brand: "Toyota",
		Model: "Corolla",
		Year:  2008,
	})
	data = append(data, Car{
		Id:    primitive.NewObjectID(),
        CreatedAt: time.Now().UTC(),
		Brand: "Ford",
		Model: "Focus",
		Year:  2021,
	})

	res, err := db.Collection("cars").InsertMany(context.Background(), data)
	if err != nil {
		log.Fatal(err)
	}

	// 2 documents inserted
	log.Printf("%v documents inserted", len(res.InsertedIDs))
}

Finding Single Document From MongoDB with Golang

To find a single document with a condition, we can use the FindOne() method of *Collection object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
	Id        primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
	Brand     string             `bson:"brand"`
	Model     string             `bson:"model"`
	Year      int                `bson:"year"`
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

    condition := bson.M{}
    cur, err := db.Collection("cars").FindOne(context.Background(), condition)
	if err != nil {
		log.Fatal(err)
	}

	var data []Car
	if err := cur.All(context.Background(), &data); err != nil {
		log.Fatal(err)
	}

	// now we can use the data array, which contains all of the documents
	for _, car := range data {
		log.Printf("the brand is %v\n", car.Brand)
	}

}

Fetch the Lastly Created Document

We can also pass mongo.Options to the Find() operation. Let’s say we want to fetch the lastly inserted document.

  • we need to sort by the createdAt field
  • it should be descending, that’s why we made the sort value as -1.
1
2
3
4
5
6
7
var opts = options.FindOne().SetSort(bson.M{
    "createdAt": -1,
})
res := db.Collection("cars").FindOne(context.Background(), bson.M{}, opts)
if res.Err() != nil {
    log.Fatal(err)
}

Finding All Documents From MongoDB with Golang

To find the all documents in a collection, we can use the Find() method of *Collection object. In the below example, we did not specify any condition, which means that return all of the documents in the database.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
	Id        primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
	Brand     string             `bson:"brand"`
	Model     string             `bson:"model"`
	Year      int                `bson:"year"`
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

    condition := bson.M{}
    cur, err := db.Collection("cars").Find(context.Background(), condition)
	if err != nil {
		log.Fatal(err)
	}

	var data []Car
	if err := cur.All(context.Background(), &data); err != nil {
		log.Fatal(err)
	}

	// now we can use the data array, which contains all of the documents
	for _, car := range data {
		log.Printf("the brand is %v\n", car.Brand)
	}

}

Finding Many Documents With Condition

If we would like to return the cars where the brand is Toyota, then we can change the condition variable as

1
2
3
condition := bson.M{
    "brand": "Toyota"
}

Use Projection in Find Operations

If you want to use projection in Find() operation, we can use the mongo.Options for that. Let’s say we would like to return 2 fields

  1. return the brand of the car.
  2. return a boolean field to check if the car is new
    1. if the production year of the car is 2022, it is new
    2. else, it is old.

SetProjection() sets the value for the projection field.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var opts = options.Find().SetProjection(
		bson.M{
			"brand": 1,
			"isNew": bson.M{
				"$cond": bson.M{
					"if": bson.M{"$gte": bson.A{"$year", 2022}}, 
					"then": true, 
					"else": false},
			},
		})
cur, err := db.Collection("cars").Find(context.Background(), bson.M{}, opts)

More will come, so please stay tuned!

Update Single Document in MongoDB With Golang

To update a single document, we should use the FindOneAndUpdate() or UpdateOne() operations. For this blog, we will use the FindOneAndUpdate() operation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

	filter := bson.M{
		"brand": "Toyota",
		"model": "Corolla",
	}

	update := bson.M{
		"year": 2022,
	}

	res := db.Collection("cars").FindOneAndUpdate(context.Background(), filter, update)

	if res.Err() != nil {
		log.Fatal(err)
	}

	// operation successful
}

How to return the updated document in MongoDB?

We can use mongo.Options package to do that. We should set the return document option to after.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
opts := options.FindOneAndUpdate().SetReturnDocument(options.After)

res := db.Collection("cars").FindOneAndUpdate(context.Background(), filter, update, opts)

// we can use the updated car document
var updatedData Car

if err := res.Decode(&updatedData); err != nil {
	log.Fatal(err)
}

Delete Document(s) from MongoDB with Golang

To delete a document we can use DeleteOne() method of the *Collection object.

To delete many documents, we can use the DeleteMany() method of the *Collection

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
	"context"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	db := client.Database("testdb")

	filter := bson.M{
		"brand": "Toyota",
		"model": "Corolla",
	}

	// for single document
	res, err := db.Collection("cars").DeleteMany(context.Background(), filter)

	if err != nil {
		log.Fatal(err)
	}

	// 1 document is deleted.
	log.Printf("%v document is deleted", res.DeletedCount)
}

More will come, so please stay tuned!