All Projects → tfogo → mongodb-go-tutorial

tfogo / mongodb-go-tutorial

Licence: other
Example using the MongoDB Go Driver

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to mongodb-go-tutorial

Objcmongodb
Mac OS and iOS library for MongoDB and BSON
Stars: ✭ 166 (+45.61%)
Mutual labels:  driver, bson
Mongo Cxx Driver
C++ Driver for MongoDB
Stars: ✭ 792 (+594.74%)
Mutual labels:  driver, bson
Paperino
E-Paper display library for the Particle & Arduino family.
Stars: ✭ 35 (-69.3%)
Mutual labels:  driver
OpenDriver2Tools
Driver 1 and Driver 2 tools
Stars: ✭ 25 (-78.07%)
Mutual labels:  driver
state-farm-distracted-driver-detection
Automatically classification of each driver's behavior given a dataset of 2D dashboard camera images.
Stars: ✭ 32 (-71.93%)
Mutual labels:  driver
vboxpower
VirtualBox Power Driver for MAAS
Stars: ✭ 107 (-6.14%)
Mutual labels:  driver
realtek rtwifi
Realtek RTWIFI - RTL8XXXU mod
Stars: ✭ 32 (-71.93%)
Mutual labels:  driver
KMAC
Some usefull info when reverse engineering Kernel Mode Anti-Cheat
Stars: ✭ 31 (-72.81%)
Mutual labels:  driver
wiasane
Scanner Access Now Easy - WIA Driver
Stars: ✭ 109 (-4.39%)
Mutual labels:  driver
phpRedisTimeSeries
📈 Use Redis Time Series in PHP!
Stars: ✭ 23 (-79.82%)
Mutual labels:  driver
Driver.NET
Lightweight and flexible library to load and communicate with kernel drivers on Windows.
Stars: ✭ 59 (-48.25%)
Mutual labels:  driver
nativeble
A fully-fledged cross-platform BLE library for desktop.
Stars: ✭ 15 (-86.84%)
Mutual labels:  driver
cdrs-tokio
High-level async Cassandra client written in 100% Rust.
Stars: ✭ 54 (-52.63%)
Mutual labels:  driver
Meteor-logger
🧾 Meteor isomorphic logger. Store application logs in File (FS), MongoDB, or print in Console
Stars: ✭ 51 (-55.26%)
Mutual labels:  driver
linux nvidia jetson
Allied Vision CSI-2 camera driver for NVIDIA Jetson Systems. Currently supporting Nano, TX2, AGX Xavier, and Xavier NX. Support for TX2 NX coming soon.
Stars: ✭ 68 (-40.35%)
Mutual labels:  driver
rtl88x2BU WiFi linux v5.2.4.1 22719 COEX20170518-4444.20170613
rtl88x2bu driver updated for modern kernels.
Stars: ✭ 26 (-77.19%)
Mutual labels:  driver
rust-radio-sx127x
Rust driver for the Semtech SX127x series of Sub-GHz LoRa/ISM radio transceivers
Stars: ✭ 21 (-81.58%)
Mutual labels:  driver
mlx90632-library
MLX90632 library for the Melexis 90632 Infra Red temperature sensor.
Stars: ✭ 34 (-70.18%)
Mutual labels:  driver
swoole-postgresql-doctrine-driver
🔌 A Doctrine DBAL Driver implementation on top of Swoole Coroutine PostgreSQL client
Stars: ✭ 15 (-86.84%)
Mutual labels:  driver
WindowsIoTEverywhere
Images & drivers to get WIndows 10 IoT running on off-the-shelf tablets, mini-pcs, and various computers.
Stars: ✭ 23 (-79.82%)
Mutual labels:  driver

MongoDB Go Driver Tutorial Part 1: Connecting, Using BSON, and CRUD Operations

The official MongoDB Go Driver recently moved to GA with the release of version 1.0.0. It's now regarded as feature complete and ready for production use. This tutorial will help you get started with the MongoDB Go Driver. You will create a simple program and learn how to:

  • Install the MongoDB Go Driver
  • Connect to MongoDB using the Go Driver
  • Use BSON objects in Go
  • Send CRUD operations to MongoDB

You can view the complete code for this tutorial on this GitHub repository. In order to follow along, you will need a MongoDB database to which you can connect. You can use a MongoDB database running locally, or easily create a free 500 MB database using MongoDB Atlas.

Install the MongoDB Go Driver

The MongoDB Go Driver is made up of several packages. If you are just using go get, you can install the driver using:

go get go.mongodb.org/mongo-driver

The output of this may look like a warning stating something like package go.mongodb.org/mongo-driver: no Go files in (...). This is expected output from go get.

If you are using the dep package manager, you can install the main mongo package as well as the bson and mongo/options package using this command:

dep ensure --add go.mongodb.org/mongo-driver/mongo \
go.mongodb.org/mongo-driver/bson \
go.mongodb.org/mongo-driver/mongo/options

If you are using go mod, the correct packages should be retrieved at build time.

Create the wireframe

Create the file main.go and import the bson, mongo, and mongo/options packages:

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"
)

// You will be using this Trainer type later in the program
type Trainer struct {
    Name string
    Age  int
    City string
}

func main() {
    // Rest of the code will go here
}

This code also imports some standard libraries and defines a Trainer type. You will be using these later in the tutorial.

Connect to MongoDB using the Go Driver

Once the MongoDB Go Driver has been imported, you can connect to a MongoDB deployment using the mongo.Connect() function. You must pass a context and a options.ClientOptions object to mongo.Connect(). The client options are used to set the connection string. It can also be used to configure driver settings such as write concerns, socket timeouts, and more. The options package documentation has more information about what client options are available.

Add this code in the main function:

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

// Connect to MongoDB
client, err := mongo.Connect(context.TODO(), clientOptions)

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

// Check the connection
err = client.Ping(context.TODO(), nil)

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

fmt.Println("Connected to MongoDB!")

Once you have connected, you can now get a handle for the trainers collection in the test database by adding the following line of code at the end of the main function:

collection := client.Database("test").Collection("trainers")

The following code will use this collection handle to query the trainers collection.

It is best practice to keep a client that is connected to MongoDB around so that the application can make use of connection pooling - you don't want to open and close a connection for each query. However, if your application no longer requires a connection, the connection can be closed with client.Disconnect() like so:

err = client.Disconnect(context.TODO())

if err != nil {
    log.Fatal(err)
}
fmt.Println("Connection to MongoDB closed.")

Run the code (go run main.go) to test that your program can successfully connect to your MongoDB server. Go will complain about the unused bson and mongo/options packages and the unused collection variable, since we haven't done anything with them yet. You have to comment these out until they are used to make your program run and test the connection.

Use BSON Objects in Go

Before we start sending queries to the database, it's important to understand how the Go Driver works with BSON objects. JSON documents in MongoDB are stored in a binary representation called BSON (Binary-encoded JSON). Unlike other databases that store JSON data as simple strings and numbers, the BSON encoding extends the JSON representation to include additional types such as int, long, date, floating point, and decimal128. This makes it much easier for applications to reliably process, sort, and compare data. The Go Driver has two families of types for representing BSON data: The D types and the Raw types.

The D family of types is used to concisely build BSON objects using native Go types. This can be particularly useful for constructing commands passed to MongoDB. The D family consists of four types:

  • D: A BSON document. This type should be used in situations where order matters, such as MongoDB commands.
  • M: An unordered map. It is the same as D, except it does not preserve order.
  • A: A BSON array.
  • E: A single element inside a D.

Here is an example of a filter document built using D types which may be used to find documents where the name field matches either Alice or Bob:

bson.D{{
    "name", 
    bson.D{{
        "$in", 
        bson.A{"Alice", "Bob"}
    }}
}}

The Raw family of types is used for validating a slice of bytes. You can also retrieve single elements from Raw types using a Lookup(). This is useful if you don't want the overhead of having to unmarshall the BSON into another type. This tutorial will just use the D family of types.

CRUD Operations

Once you have connected to the database, it's time to start adding and manipulating some data. The Collection type has several methods which allow you to send queries to the database.

Insert documents

First, create some new Trainer structs to insert into the database:

ash := Trainer{"Ash", 10, "Pallet Town"}
misty := Trainer{"Misty", 10, "Cerulean City"}
brock := Trainer{"Brock", 15, "Pewter City"}

To insert a single document, use the collection.InsertOne() method:

insertResult, err := collection.InsertOne(context.TODO(), ash)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted a single document: ", insertResult.InsertedID)

To insert multiple documents at a time, the collection.InsertMany() method will take a slice of objects:

trainers := []interface{}{misty, brock}

insertManyResult, err := collection.InsertMany(context.TODO(), trainers)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)

Update documents

The collection.UpdateOne() method allows you to update a single document. It requires a filter document to match documents in the database and an update document to describe the update operation. You can build these using bson.D types:

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

update := bson.D{
    {"$inc", bson.D{
        {"age", 1},
    }},
}

This code will then match the document where the name is Ash and will increment Ash's age by 1 - happy birthday Ash!

updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)

Find documents

To find a document, you will need a filter document as well as a pointer to a value into which the result can be decoded. To find a single document, use collection.FindOne(). This method returns a single result which can be decoded into a value. You'll use the same filter variable you used in the update query to match a document where the name is Ash.

// create a value into which the result can be decoded
var result Trainer

err = collection.FindOne(context.TODO(), filter).Decode(&result)
if err != nil {
    log.Fatal(err)
}

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

To find multiple documents, use collection.Find(). This method returns a Cursor. A Cursor provides a stream of documents through which you can iterate and decode one at a time. Once a Cursor has been exhausted, you should close the Cursor. Here you'll also set some options on the operation using the options package. Specifically, you'll set a limit so only 2 documents are returned.

// Pass these options to the Find method
findOptions := options.Find()
findOptions.SetLimit(2)

// Here's an array in which you can store the decoded documents
var results []*Trainer

// Passing bson.D{{}} as the filter matches all documents in the collection
cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions)
if err != nil {
    log.Fatal(err)
}

// Finding multiple documents returns a cursor
// Iterating through the cursor allows us to decode documents one at a time
for cur.Next(context.TODO()) {
    
    // create a value into which the single document can be decoded
    var elem Trainer
    err := cur.Decode(&elem)
    if err != nil {
        log.Fatal(err)
    }

    results = append(results, &elem)
}

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

// Close the cursor once finished
cur.Close(context.TODO())

fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)

Delete Documents

Finally, you can delete documents using collection.DeleteOne() or collection.DeleteMany(). Here you pass bson.D{{}} as the filter argument, which will match all documents in the collection. You could also use collection.Drop() to delete an entire collection.

deleteResult, err := collection.DeleteMany(context.TODO(), bson.D{{}})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)

Next steps

You can view the final code from this tutorial in this GitHub repository. Documentation for the MongoDB Go Driver is available on GoDoc. You may be particularly interested in the documentation about using aggregations or transactions.

If you have any questions, please get in touch in the mongo-go-driver Google Group. Please file any bug reports on the Go project in the MongoDB JIRA. We would love your feedback on the Go Driver, so please get in touch with us to let us know your thoughts.

This is part one of several tutorials on the Go Driver. The next part will be:

  • MongoDB Go Driver Tutorial Part 2: BSON Tags and Primitive Types

So stay tuned for more parts in the coming weeks.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].