Christian Giacomi

MongoDB index using Go

Posted — Mar 15, 2020

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.

Disclaimer

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…

Mongo-Go-Driver

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

Collection

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.

IndexView

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.

Helper Function

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.

Connect to Mongo

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

Create Index

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.

Use

This is how simple it is to use the helper function above

unique := false
CreateIndex("CollectionName", "fieldName", unique)

Conclusion

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.

If this post was helpful tweet it or share it.

See Also