This month’s post will not be as long as the one from last month, and will focus on a small area regarding MongoDB.
When I started using Go, and the official mongo-go-driver, one of the issues that I ran into was the creation of indexes, and coming from a NodeJS experience using Mongoose it was extremely simple. So I decided to write this small post to help out anyone that might find themselves in the same situation I was in.
I will assume that you are reading this post because you already know what a MongoDB index is, and why you might need it and are only interested in how to implement it using Go and the mongo-go-driver.
Should you NOT be familiar with indexes in general, or even indexes in a MongoDB context, please take a look at this really great article by Orlando Monteverde - “Golang and MongoDB with go-mongo-driver”
So let’s start indexing…
Not to criticize Mongo, but when you go to the official Go driver repo, you will not find any examples regarding indexes and how to define them using Go.
So if we take a look instead at the Mongo driver’s page we will see that under the Go documentation there is a link to the General Documentation for the Mongo Go Driver which contains the listing of all the functions and types related to the driver. It’s a long list, but please don’t despair…
For the purpose of completeness these are the functions you will be dealing with from the driver.
Let’s start looking at how we can work with Indexes
From a Collection
type we can easily get access to the IndexView
type which we will need to perform any operations on the database in regards to indexes.
func (coll *Collection) Indexes() IndexView
Indexes returns an IndexView instance that can be used to perform operations on the indexes for the collection.
As the documentation clearly states: “IndexView is a type that can be used to create, drop, and list indexes on a collection. An IndexView for a collection can be created by a call to Collection.Indexes()."
The following are the functions you can use to interact with indexes using the official MongoDB driver.
func (IndexView) CreateMany
Allows you to create multiple indexes at the same time.
func (IndexView) CreateOne
Allows you to create a single index in a collection.
func (IndexView) DropAll
Drops all the indexes currently present in a collection.
func (IndexView) DropOne
Drops a single index present in a collection.
func (IndexView) List
Lists all the indexes present in a collection.
Since I promised I would keep this post short I will not be showing you examples for every one of the functions listed above, but I will be sharing the helper function I use to create indexes.
I like to keep things simple, and readability is very important for me, so when I need to create multiple indexes I usually always create each one individually and independently of each other, but you are of course free to do as you think is best for you.
To connect to Mongo you will need something like the function below.
func Database() *mongo.Database {
opt := options.Client().ApplyURI("mongodb://localhost:27017")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, opt)
if err != nil {
log.Fatal(err.Error())
}
return client.Database("SomeDatabase")
}
This is a simple helper function to create a single index.
// CreateIndex - creates an index for a specific field in a collection
func CreateIndex(collectionName string, field string, unique bool) bool {
// 1. Lets define the keys for the index we want to create
mod := mongo.IndexModel{
Keys: bson.M{field: 1}, // index in ascending order or -1 for descending order
Options: options.Index().SetUnique(unique),
}
// 2. Create the context for this operation
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 3. Connect to the database and access the collection
collection := Database().Collection(collectionName)
// 4. Create a single index
_, err := collection.Indexes().CreateOne(ctx, mod)
if err != nil {
// 5. Something went wrong, we log it and return false
fmt.Println(err.Error())
return false
}
// 6. All went well, we return true
return true
}
As you can see the code is very readable and I have added some comments to further explain what is going on.
This is how simple it is to use the helper function above
unique := false
CreateIndex("CollectionName", "fieldName", unique)
As you can clearly see it is very simple to create an index in MongoDB using Go, furthermore you can easily modify the helper function to suit your needs, and doing so you can take full advantage of all the functions provided by the official driver.