Getting Started with the MongoDB Go Driver

Akash Kathiriya

In March 2019 the official, production-ready GO driver for MongoDB was released and it’s been receiving continuous updates from its launch. In this tutorial, we will learn to do simple MongoDB CRUD operations using Go driver.

Prerequisites

Two things are required before we start with this tutorial.

  • Go should be installed on your machine. Go version 1.15 is used for this tutorial. You can download the Go package from this link.
  • Install the latest version of MongoDB on your machine and start the local server of MongoDB.

Installation of the MongoDB Driver

Install the MongoDB go driver by running the following command:

go get go.mongodb.org/mongo-driver

If you are using Go Modules then create a go.mod file and then the above command will add the required dependency in the mod file. This file locks all the project requirements to its correct version.

Setting Up the Main File

Create a file main.go in your project folder and open it in your IDE. Before we write the code for MongoDB operations, let’s import all the necessary packages in the file.

package main

import (

  "context"

  "fmt"

  "log"



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

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

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

)

Now, Create the following global variables which we will use across all the CRUD operation functions.

var client *mongo.Client

var collection *mongo.Collection

var ctx = context.TODO()

Also, create the structure for document type.

type Person struct {

Name string

Age  int

City string

}

Connecting to MongoDB

Now the base setup is ready. Let’s create our first function for connecting to MongoDB.

func connect() *mongo.Client {

  clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

  client, err := mongo.Connect(ctx, clientOptions)

  if err != nil {

       log.Fatal(err)

  }

err = client.Ping(ctx, nil)

  if err != nil {

       log.Fatal(err)

  }

  fmt.Println("Connected to MongoDB!")

  return client

}

This function will set up the connection with our locally running MongoDB and return the client object.  Once the connect method returns the client object, we can use the Ping() method to check whether the connection was successful or not. If the Ping() method returns any error, we can raise the error and return.

Insert Operation

To insert only one document, we can use insertOne method and to insert multiple documents together, we can use insertMany method. Following is the function for inserting one document in the Person collection:

func insertOne() {

  akash := Person{"Akash", 28, "Bengaluru"}

  res, err := collection. InsertOne (ctx, akash)

  if err != nil {

       log.Fatal(err)

  }

  fmt.Println("Inserted document: ", res.InsertedID)

}

Here is the function for adding multiple documents to the collection:

func insertMany() {

  akash := Person{"Akash", 28, "Bengaluru"}

  bob := Person {"Bob", 30, "New York"}

  robin := Person {"Robin", 25, "London"}

 

  persons := []interface{}{akash, bob, robin}



  res, err := collection.InsertMany(ctx, persons)

  if err != nil {

       log.Fatal(err)

  }

  fmt.Println("Inserted documents: ", res.InsertedIDs)

}

For both operations, we need to use Person struct which we created earlier and initialize it with our data. With the InsertMany function, we will require to pass the type interface for all documents.

Retrieve Operation

For finding data from the collection, we will require a pass filter so make sure that you have imported the bson package. We will use bson.D type to create filters using bson objects.

func retrieveOne() {

  var result Person

  filter := bson.D{{"name", "Akash"}}

  err := collection.FindOne(ctx, filter).Decode(&result)

  if err != nil {

       log.Fatal(err)

  }

  fmt.Printf("Found a single document: %+v\n", result)

}

Same way, we can use the Find method to retrieve all the matching documents.

func retrieveAll() {

  findOptions := options.Find()

  findOptions.SetLimit(2)

  var results []*Person

  cur, err := collection.Find(ctx, bson.D{{}}, findOptions)

  if err != nil {

       log.Fatal(err)

  }

  // Loop through the cursor

  for cur.Next(context.TODO()) {

       var elem Person

       err := cur.Decode(&elem)

       if err != nil {

            log.Fatal(err)

       }

       results = append(results, &elem)

  }

  if err := cur.Err(); err != nil {

       log.Fatal(err)

  }

  cur.Close(context.TODO())

}

You can use the options package to specify options like limit or orders.

Update Operation

Same as FineOne method, for update also you can use UpdateOne method with bson filter object. This code will update all the documents with the name Akash and increase the value of Age by one.

func update() {

filter := bson.D{{"name", "Akash"}}

update := bson.D{

     {"$inc", bson.D{

         {"Age", 1},

     }},

}

updateResult, err := collection.UpdateOne(context.TODO(), filter, update)

if err != nil {

     log.Fatal(err)

}

fmt.Printf("Updated documents: %+v\n", updateResult)

}

Delete Operation

For deleting documents from any collection, you can use either DeleteOne or DeleteMany method. Here also, we can pass bson filter objects to match the documents and delete them.

func delete() {

deleteResult, err := collection.DeleteMany(ctx, bson.D{{}})

if err != nil {

     log.Fatal(err)

}

fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)

}

If you pass bson.D{{}} object as a filter parameter then it will delete all the documents. You can use collection.Drop() method to drop the entire collection.

Once all these functions are ready, you can use them in your driver function according to your need. Hopefully, this will be enough to get you started with writing MongoDB functions in Go. For more information, you can refer to official documentation for the Go Mongo driver.

ClusterControl
The only management system you’ll ever need to take control of your open source database infrastructure.