Go, MongoDB, MongoLab, mgo and Heroku

Satish Manohar Talim
6 min readSep 25, 2015

--

Part 1

These study notes is an attempt to write about Go, MongoDB, MongoLab, mgo and Heroku as I explore and experiment, in the hope that a new Go developer can understand and get up-to-speed with it in no time.

What’s NoSQL?

In the words of Karl Seguin:

NoSQL is a broad term that means different things to different people. Personally, I use it very broadly to mean a system that plays a part in the storage of data. Put another way, NoSQL (again, for me), is the belief that your persistence layer isn’t necessarily the responsibility of a single system. Where relational database vendors have historically tried to position their software as a one-size-fits-all solution, NoSQL leans towards smaller units of responsibility where the best tool for a given job can be leveraged. So, your NoSQL stack might still leverage a relational database, say MySQL, but it’ll also contain Redis as a persistence lookup for specific parts of the system as well as Hadoop for your intensive data processing. Put simply, NoSQL is about being open and aware of alternative, existing and additional patterns and tools for managing your data.

You might be wondering where MongoDB fits into all of this. As a document-oriented database, Mongo is a more generalized NoSQL solution. It should be viewed as an alternative to relational databases. Like relational databases, it too can benefit from being paired with some of the more specialized NoSQL solutions.

Also, most web apps will use either a relational or document-oriented database. A number of Platform-as-a-Service (PaaS) providers allow you to use Go applications on their cloud. Later on, we would use Heroku and access our MongoDB database on MongoLab.

What’s MongoDB?

MongoDB is an open-source document database that provides high performance, high availability, and automatic scaling.

MongoDB Core Concepts

  • MongoDB has the same concept of a “database” with which you are likely already familiar (or a schema for you Oracle folks). Within a MongoDB instance you can have zero or more databases, each acting as high-level containers for everything else.
  • A database can have zero or more “collections”. A collection shares enough in common with a traditional “table” that you can safely think of the two as the same thing.
  • Collections are made up of zero or more “documents”. Again, a document can safely be thought of as a “row”.
  • A document is made up of one or more “fields”, which you can probably guess are a lot like “columns”.
  • Indexes” in MongoDB function much like their RDBMS counterparts.
  • Cursors” are different than the other five concepts, but they are important enough. The important thing to understand about cursors is that when you ask MongoDB for data, it returns a cursor, which we can do things to, such as counting or skipping ahead, without actually pulling down data.

To recap, MongoDB is made up of databases which contain collections. A collection is made up of documents. Each document is made up of fields. Collections can be indexed, which improves lookup and sorting performance. Finally, when we get data from MongoDB we do so through a cursor whose actual execution is delayed until necessary.

MongoDB

Note: The core difference between relational databases and document-oriented databases comes from the fact that relational databases define columns at the table level whereas a document-oriented database defines its fields at the document level.

MongoLab — The Fully-managed MongoDB-as-a-Service

MongoLab is a platform for MongoDB hosting on the web.

Sign Up

Sign up for a free account. When you fill up the online form, remember what you enter for default username and password — we will need this information later on. Next, click on “Plans & Features” and then select the free Sandbox plan.

Create a database subscription

We will create a new subscription from scratch.

  1. Log in to the MongoLab management portal
  2. On your account’s Home page, click the “Create new” button
  3. Make all the desired selections and fill in the requested fields (select the “Plan” Single-node; “Standard Line” Sandbox and enter “Database name” say godata)
  4. Review your choices and when you’re ready, click the “Create new MongoDB deployment” button
  5. When the subscription has completed building, your new deployment will be listed on your account’s Home page.

To connect using a driver via the standard URI:

mongodb://<dbuser>:<dbpassword>@ds051523.mongolab.com:51523/godata

Database User

On your home page, click on godata. On the new page that comes up, it says “ A database user is required to connect to this database. Click here to create a new one.” I entered “IndianGuru” for a Database username (you can enter whatever you want) and the requisite password.

mgo

Of all the Go drivers available for MongoDB, mgo is the most advanced and well-maintained.

To install “mgo”, in a command window type:

go get gopkg.in/mgo.v2

package mgo

Usage: import “gopkg.in/mgo.v2”

The mgo project (pronounced as “mango”) is a rich MongoDB driver for the Go language.

Usage of the driver revolves around the concept of sessions. To get started, obtain a session using the Dial function:

session, err := mgo.Dial(url)

This will establish one or more connections with the cluster of servers defined by the “url” parameter. From then on, the cluster may be queried and documents retrieved with statements such as:

c := session.DB(database).C(collection)
err := c.Find(query).One(&result)

Once the session is not useful anymore, “Close” must be called to release the resources appropriately.

Function Close

func (s *Session) Close()

Close terminates the session. It’s a runtime error to use a session after it has been closed.

Function SetSafe

func (s *Session) SetSafe(safe *Safe)

SetSafe changes the session safety mode. If the safe parameter is “nil”, the session is put in unsafe mode and writes become fire-and-forget, without error checking. The unsafe mode is faster since operations won’t hold on waiting for a confirmation.

The following statement will make the session check for errors, without imposing further constraints:

session.SetSafe(&mgo.Safe{})

Function Safe

func (s *Session) Safe() (safe *Safe)

Safe returns the current safety mode for the session.

Function DB

func (s *Session) DB(name string) *Database

DB returns a value representing the named database (in our case “godata”). If the name is empty, the database name provided in the dialed URL is used instead. If that is also empty, “test” is used as a fallback.

Function C

func (db *Database) C(name string) *Collection

C returns a value representing the named collection (in our case “user”).

Function Insert

func (c *Collection) Insert(docs …interface{}) error

Insert inserts one or more documents in the respective collection.

Function Find

func (c *Collection) Find(query interface{}) *Query

Find prepares a query using the provided document. The document may be a map or a struct value capable of being marshalled with “bson”. The map may be a generic one using interface{} for its key and/or values, such as “bson.M”, or it may be a properly typed map. Providing “nil” as the document is equivalent to providing an empty document such as “bson.M{}”.

Further details of the query may be tweaked using the resulting Query value, and then executed to retrieve results using methods such as “One”, “For”, “Iter”, or “Tail”.

Function One

func (q *Query) One(result interface{}) (err error)

One executes the query and unmarshals the first obtained document into the result argument. The result must be a struct or map value capable of being unmarshalled into by “gobson”. This function blocks until either a result is available or an error happens.

package bson

Usage: import “labix.org/v2/mgo/bson”

Package bson is an implementation of the BSON specification for Go.

type M

type M map[string]interface{}

M is a convenient alias for a “map[string]interface{}” map, useful for dealing with BSON in a native way. For instance:

bson.M{“a”: 1, “b”: true}

Program mongohqconnect.go

The program “mongohqconnect.go” connects to our database “godata” hosted on MongoLab and creates a collection “user”.

When you run the program, the output is:

Email Id: csonpatki@gmail.com

In Part 2 we will learn how to deploy our Go app to Heroku.

Note: I would love your feedback on these study notes. If I can make it better, I’d love it!

--

--

Satish Manohar Talim

Senior Technical Evangelist at GoProducts Engineering India LLP, Co-Organizer GopherConIndia. Director JoshSoftware and Maybole Technologies. #golang hobbyist