How to Use Go With MongoDB?
MongoDB is an open-source NoSQL database. It is a document-oriented database, uses a JSON-like structure called BSON to store documents(i.e. key-value pairs). MongoDB provides the concept of collection to group documents. In this article, we will discuss who connects MongoDB with Golang.
Prerequisite: You need to install MongoDB and start it on the default port(i.e. 27017).
Installation: Package mongo provides a MongoDB Driver API for Go, which can be used to interact with MongoDB API. Use the below command to install package mongo.
go get go.mongodb.org/mongo-driver/mongo
Package context: Package context is the context type, which holds deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
Connect Go driver with MongoDB
Now to connect the Go driver with MongoDB you need to follow the following steps:
- Create mongo.Client with mongo.Connect function. The mongo.Client handles the connection with the MongoDB.
- mongo.Client has a method called Ping which returns pong on the successful connection.
- Finally, use mongo.Client.Disconnect to close the Database connection.
Go
package main import ( "context" "fmt" "time" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) // This is a user defined method to close resources. // This method closes mongoDB connection and cancel context. func close(client *mongo.Client, ctx context.Context, cancel context.CancelFunc){ // CancelFunc to cancel to context defer cancel() // client provides a method to close // a mongoDB connection. defer func (){ // client.Disconnect method also has deadline. // returns error if any, if err := client.Disconnect(ctx); err != nil{ panic(err) } }() } // This is a user defined method that returns mongo.Client, // context.Context, context.CancelFunc and error. // mongo.Client will be used for further database operation. // context.Context will be used set deadlines for process. // context.CancelFunc will be used to cancel context and // resource associated with it. func connect(uri string )(*mongo.Client, context.Context, context.CancelFunc, error) { // ctx will be used to set deadline for process, here // deadline will of 30 seconds. ctx, cancel := context.WithTimeout(context.Background(), 30 * time.Second) // mongo.Connect return mongo.Client method client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) return client, ctx, cancel, err } // This is a user defined method that accepts // mongo.Client and context.Context // This method used to ping the mongoDB, return error if any. func ping(client *mongo.Client, ctx context.Context) error{ // mongo.Client has Ping to ping mongoDB, deadline of // the Ping method will be determined by cxt // Ping method return error if any occurred, then // the error can be handled. if err := client.Ping(ctx, readpref.Primary()); err != nil { return err } fmt.Println( "connected successfully" ) return nil } func main(){ // Get Client, Context, CancelFunc and // err from connect method. client, ctx, cancel, err := connect( "mongodb://localhost:27017" ) if err != nil { panic(err) } // Release resource when the main // function is returned. defer close(client, ctx, cancel) // Ping mongoDB with Ping method ping(client, ctx) } |
Output:
Inserting Documents
To insert documents you need to follow the following steps:
- Create mongo.Client with mongo.Connect function. The mongo.Client handles the connection with the MongoDB.
- mongo.Client.Database returns a pointer type to the database.
- Pointer to the database has method collection to select a collection to work with.
- Collection type provides two methods to insert a document into MongoDB.
- Collection.InsertOne() method can insert one document into the database.
- Collection.InsertMany() method can insert a list of documents.
- Then finally use mongo.Client.Disconnect to close the Database connection.
Go
package main import ( "context" "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) // This is a user defined method to close resources. // This method closes mongoDB connection and cancel context. func close(client *mongo.Client, ctx context.Context, cancel context.CancelFunc){ defer cancel() defer func () { if err := client.Disconnect(ctx); err != nil { panic(err) } }() } // This is a user defined method that returns mongo.Client, // context.Context, context.CancelFunc and error. // mongo.Client will be used for further database operation. // context.Context will be used set deadlines for process. // context.CancelFunc will be used to cancel context and // resource associated with it. func connect(uri string ) (*mongo.Client, context.Context, context.CancelFunc, error) { ctx, cancel := context.WithTimeout(context.Background(), 30 * time.Second) client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) return client, ctx, cancel, err } // insertOne is a user defined method, used to insert // documents into collection returns result of InsertOne // and error if any. func insertOne (client *mongo.Client, ctx context.Context, dataBase, col string , doc interface {}) (*mongo.InsertOneResult, error) { // select database and collection ith Client.Database method // and Database.Collection method collection := client.Database(dataBase).Collection(col) // InsertOne accept two argument of type Context // and of empty interface result, err := collection.InsertOne(ctx, doc) return result, err } // insertMany is a user defined method, used to insert // documents into collection returns result of // InsertMany and error if any. func insertMany (client *mongo.Client, ctx context.Context, dataBase, col string , docs [] interface {}) (*mongo.InsertManyResult, error) { // select database and collection ith Client.Database // method and Database.Collection method collection := client.Database(dataBase).Collection(col) // InsertMany accept two argument of type Context // and of empty interface result, err := collection.InsertMany(ctx, docs) return result, err } func main() { // get Client, Context, CancelFunc and err from connect method. client, ctx, cancel, err := connect( "mongodb://localhost:27017" ) if err != nil { panic(err) } // Release resource when main function is returned. defer close(client, ctx, cancel) // Create a object of type interface to store // the bson values, that we are inserting into database. var document interface {} document = bson.D{ { "rollNo" , 175 }, { "maths" , 80 }, { "science" , 90 }, { "computer" , 95 }, } // insertOne accepts client , context, database // name collection name and an interface that // will be inserted into the collection. // insertOne returns an error and a result of // insert in a single document into the collection. insertOneResult, err := insertOne(client, ctx, "gfg" , "marks" , document) // handle the error if err != nil { panic(err) } // print the insertion id of the document, // if it is inserted. fmt.Println( "Result of InsertOne" ) fmt.Println(insertOneResult.InsertedID) // Now will be inserting multiple documents into // the collection. create a object of type slice // of interface to store multiple documents var documents [] interface {} // Storing into interface list. documents = [] interface {}{ bson.D{ { "rollNo" , 153 }, { "maths" , 65 }, { "science" , 59 }, { "computer" , 55 }, }, bson.D{ { "rollNo" , 162 }, { "maths" , 86 }, { "science" , 80 }, { "computer" , 69 }, }, } // insertMany insert a list of documents into // the collection. insertMany accepts client, // context, database name collection name // and slice of interface. returns error // if any and result of multi document insertion. insertManyResult, err := insertMany(client, ctx, "gfg" , "marks" , documents) // handle the error if err != nil { panic(err) } fmt.Println( "Result of InsertMany" ) // print the insertion ids of the multiple // documents, if they are inserted. for id := range insertManyResult.InsertedIDs { fmt.Println(id) } } |
Output:
Finding Documents
To find documents you need to follow the following steps:
- Create mongo.Client with mongo.Connect function. The mongo.Client handles the connection with the MongoDB.
- mongo.Client.Database returns a pointer type to the database.
- Pointer to the database has method collection to select a collection to work with.
- The collection provides the Find() method to query the database.
- Then finally use mongo.Client.Disconnect to close the Database connection.
Go
package main import ( "context" "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) // This is a user defined method to close resources. // This method closes mongoDB connection and cancel context. func close(client *mongo.Client, ctx context.Context, cancel context.CancelFunc) { defer cancel() defer func () { if err := client.Disconnect(ctx); err != nil { panic(err) } }() } // This is a user defined method that returns // a mongo.Client, context.Context, // context.CancelFunc and error. // mongo.Client will be used for further database // operation. context.Context will be used set // deadlines for process. context.CancelFunc will // be used to cancel context and resource // associated with it. func connect(uri string ) (*mongo.Client, context.Context, context.CancelFunc, error) { ctx, cancel := context.WithTimeout(context.Background(), 30 * time.Second) client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) return client, ctx, cancel, err } // query is user defined method used to query MongoDB, // that accepts mongo.client,context, database name, // collection name, a query and field. // database name and collection name is of type // string. query is of type interface. // field is of type interface, which limits // the field being returned. // query method returns a cursor and error. func query(client *mongo.Client, ctx context.Context, dataBase, col string , query, field interface {}) (result *mongo.Cursor, err error) { // select database and collection. collection := client.Database(dataBase).Collection(col) // collection has an method Find, // that returns a mongo.cursor // based on query and field. result, err = collection.Find(ctx, query, options.Find().SetProjection(field)) return } func main() { // Get Client, Context, CancelFunc and err from connect method. client, ctx, cancel, err := connect( "mongodb://localhost:27017" ) if err != nil { panic(err) } // Free the resource when main function is returned defer close(client, ctx, cancel) // create a filter an option of type interface, // that stores bjson objects. var filter, option interface {} // filter gets all document, // with maths field greater that 70 filter = bson.D{ { "maths" , bson.D{{ "$gt" , 70 }}}, } // option remove id field from all documents option = bson.D{{ "_id" , 0 }} // call the query method with client, context, // database name, collection name, filter and option // This method returns momngo.cursor and error if any. cursor, err := query(client, ctx, "gfg" , "marks" , filter, option) // handle the errors. if err != nil { panic(err) } var results []bson.D // to get bson object from cursor, // returns error if any. if err := cursor.All(ctx, &results); err != nil { // handle the error panic(err) } // printing the result of query. fmt.Println( "Query Result" ) for _, doc := range results { fmt.Println(doc) } } |
Output:
Updating Document
To update documents you need to follow the following steps:
- Create mongo.Client with mongo.Connect function. The mongo.Client handles the connection with the MongoDB.
- mongo.Client.Database returns a pointer type to the database.
- Pointer to the database has method collection to select a collection to work with.
- The collection provides two methods to update the documents.
- UpdateOne() method modify a single document that matching the query
- UpdateMany() method modifies every document that matching the query.
- Then finally use mongo.Client.Disconnect to close the Database connection.
Go
package main import ( "context" "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) // This is a user defined method to close resources. // This method closes mongoDB connection and cancel context. func close(client *mongo.Client, ctx context.Context, cancel context.CancelFunc) { defer cancel() defer func () { if err := client.Disconnect(ctx); err != nil { panic(err) } }() } // This is a user defined method that returns // mongo.Client, context.Context, // context.CancelFunc and error. // mongo.Client will be used for further database // operation.context.Context will be used set // deadlines for process. context.CancelFunc will // be used to cancel context and resource // associated with it. func connect(uri string ) (*mongo.Client, context.Context, context.CancelFunc, error) { ctx, cancel := context.WithTimeout(context.Background(), 30 *time.Second) client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) return client, ctx, cancel, err } // UpdateOne is a user defined method, that update // a single document matching the filter. // This methods accepts client, context, database, // collection, filter and update filter and update // is of type interface this method returns // UpdateResult and an error if any. func UpdateOne(client *mongo.Client, ctx context.Context, dataBase, col string , filter, update interface {}) (result *mongo.UpdateResult, err error) { // select the database and the collection collection := client.Database(dataBase).Collection(col) // A single document that match with the // filter will get updated. // update contains the filed which should get updated. result, err = collection.UpdateOne(ctx, filter, update) return } // UpdateMany is a user defined method, that update // a multiple document matching the filter. // This methods accepts client, context, database, // collection, filter and update filter and update // is of type interface this method returns // UpdateResult and an error if any. func UpdateMany(client *mongo.Client, ctx context.Context, dataBase, col string , filter, update interface {}) (result *mongo.UpdateResult, err error) { // select the database and the collection collection := client.Database(dataBase).Collection(col) // All the documents that match with the filter will // get updated. // update contains the filed which should get updated. result, err = collection.UpdateMany(ctx, filter, update) return } func main() { // get Client, Context, CancelFunc and err from connect method. client, ctx, cancel, err := connect( "mongodb://localhost:27017" ) if err != nil { panic(err) } // Free the resource when main function in returned defer close(client, ctx, cancel) // filter object is used to select a single // document matching that matches. filter := bson.D{ { "maths" , bson.D{{ "$lt" , 100 }}}, } // The field of the document that need to updated. update := bson.D{ { "$set" , bson.D{ { "maths" , 100 }, }}, } // Returns result of updated document and a error. result, err := UpdateOne(client, ctx, "gfg" , "marks" , filter, update) // handle error if err != nil { panic(err) } // print count of documents that affected fmt.Println( "update single document" ) fmt.Println(result.ModifiedCount) filter = bson.D{ { "computer" , bson.D{{ "$lt" , 100 }}}, } update = bson.D{ { "$set" , bson.D{ { "computer" , 100 }, }}, } // Returns result of updated document and a error. result, err = Update(client, ctx, "gfg" , "marks" , filter, update) // handle error if err != nil { panic(err) } // print count of documents that affected fmt.Println( "update multiple document" ) fmt.Println(result.ModifiedCount) } |
Output:
Deleting Documents
To delete documents you need to follow the following steps:
- Create mongo.Client with mongo.Connect function. The mongo.Client handles the connection with the MongoDB.
- mongo.Client.Database returns a pointer type to the database.
- Pointer to the database has method collection to select a collection to work with.
- The collection provides two methods to delete documents in a collection.
- DeleteOne() function removes a single document matching the query.
- DeleteMany() function removes every document that matches the query.
- Then finally use mongo.Client.Disconnect to close the Database connection.
Go
package main import ( "context" "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) // This is a user defined method to close resources. // This method closes mongoDB connection and cancel context. func close(client *mongo.Client, ctx context.Context, cancel context.CancelFunc) { defer cancel() defer func () { if err := client.Disconnect(ctx); err != nil { panic(err) } }() } // This is a user defined method that returns // mongo.Client, context.Context, //context.CancelFunc and error. // mongo.Client will be used for further // database operation. context.Context will be // used set deadlines for process. // context.CancelFunc will be used to cancel // context and resource associated with it. func connect(uri string ) (*mongo.Client, context.Context, context.CancelFunc, error) { ctx, cancel := context.WithTimeout(context.Background(), 30 * time.Second) client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) return client, ctx, cancel, err } // deleteOne is a user defined function that delete, // a single document from the collection. // Returns DeleteResult and an error if any. func deleteOne(client *mongo.Client, ctx context.Context, dataBase, col string , query interface {}) (result *mongo.DeleteResult, err error) { // select document and collection collection := client.Database(dataBase).Collection(col) // query is used to match a document from the collection. result, err = collection.DeleteOne(ctx, query) return } // deleteMany is a user defined function that delete, // multiple documents from the collection. // Returns DeleteResult and an error if any. func deleteMany(client *mongo.Client, ctx context.Context, dataBase, col string , query interface {}) (result *mongo.DeleteResult, err error) { // select document and collection collection := client.Database(dataBase).Collection(col) // query is used to match documents from the collection. result, err = collection.DeleteMany(ctx, query) return } func main() { // get Client, Context, CancelFunc and err from connect method. client, ctx, cancel, err := connect( "mongodb://localhost:27017" ) if err != nil { panic(err) } // free resource when main function is returned defer close(client, ctx, cancel) // This query delete document when the maths // field is greater than 60 query := bson.D{ { "maths" , bson.D{{ "$gt" , 60 }}}, } // Returns result of deletion and error result, err := deleteOne(client, ctx, "gfg" , "marks" , query) // print the count of affected documents fmt.Println( "No.of rows affected by DeleteOne()" ) fmt.Println(result.DeletedCount) // This query deletes documents that has // science field greater that 0 query = bson.D{ { "science" , bson.D{{ "$gt" , 0 }}}, } // Returns result of deletion and error result, err = deleteMany(client, ctx, "gfg" , "marks" , query) // print the count of affected documents fmt.Println( "No.of rows affected by DeleteMany()" ) fmt.Println(result.DeletedCount) } |
Output:
Replacing a document
To replace a document you need to follow the following steps:
- Create mongo.Client with mongo.Connect function. The mongo.Client handles the connection with the MongoDB.
- mongo.Client.Database returns a pointer type to the database.
- Pointer to the database has method collection to select a collection to work with.
- The collection provides a method to replace a document in a collection.
ReplaceOne() function replaces a single document matching the query. - Then finally use mongo.Client.Disconnect to close the Database connection.
Go
/* ReplaceOne() replaces all the existing fields except _id with the fields and values you specify. If multiple documents match the query filter passed to ReplaceOne(), the method selects and replaces the first matched document.Replace operation fails if no documents match the query filter */ package main import ( "context" "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) // This is a user defined method to close resources. // This method closes mongoDB connection and cancel context. func close(client *mongo.Client, ctx context.Context, cancel context.CancelFunc) { defer cancel() defer func () { if err := client.Disconnect(ctx); err != nil { panic(err) } }() } // This is a user defined method that returns // mongo.Client, context.Context, // context.CancelFunc and error. // mongo.Client will be used for further // database operation. context.Context will be // used set deadlines for process. // context.CancelFunc will be used to cancel // context and resource associated with it. func connect(uri string ) (*mongo.Client, context.Context, context.CancelFunc, error) { ctx, cancel := context.WithTimeout(context.Background(), 30 *time.Second) client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) return client, ctx, cancel, err } func main() { // get Client, Context, CancelFunc and err from connect method. uri := "mongodb://localhost:27017" client, ctx, cancel, err := connect(uri) if err != nil { panic(err) } // free resource when main function is returned defer close(client, ctx, cancel) //select the database and the collection collection := client.Database( "dataBase" ).Collection( "col" ) //filter object is used to select the document for replacement. filter := bson.D{{ "subjectId" , 5 }} //Replacement document replacementDoc := bson.D{{ "subjectId" , 1 }, { "subject" , "Maths" }} //Returns result of replaced document and a error result, err := collection.ReplaceOne(ctx, filter, replacementDoc) //handle error if err != nil { panic(err) } //print count of documents that affected fmt.Println( "No:of documents replaced" ) fmt.Println(result.ModifiedCount) } |