Go Migration Guide

Migrating from community drivers to the official MongoDB Go Driver

Introduction

MongoDB has released an official driver for the Go language that is appropriate for all supported database operations. This driver implements the Core and API specs, and supports MongoDB 3.2 and above.

Many developers have been using community contributed golang drivers such as mgo and variants or forks of it. Developers who are interested in migrating to the official MongoDB Go driver have many considerations when approaching a migration of their application code. This migration guide is intended to provide guidance on some commonly found differences in client code when using the MongoDB Go Driver, and present potential actions to be taken during a migration.

What is the MongoDB Go Driver

The MongoDB Go Driver is a pure go package that can be included in client applications using go package management. It allows applications to connect to MongoDB and execute commands and operations.

In order to connect to and execute commands or operations against MongoDB a user must communicate with MongoDB using the MongoDB Wire Protocol. The MongoDB Go Driver implements the MongoDB Driver Specs that indicate how a driver should present the wire protocol to a user and what the user can expect as a response from the driver. There are drivers for many languages that all implement and adhere to this common set of specs, providing idiomatic access for developers to connect and work with MongoDB in their chosen language.

Why migrate to the MongoDB Go Driver

While several options exist for community supported drivers, the MongoDB Go Driver is the only Go Driver supported by MongoDB engineers. The driver is released with Spec Compliant APIs and functionality, as well as support for the latest MongoDB functionality such as multi-document ACID transactions and logical sessions. The MongoDB Go Driver includes a BSON library that is flexible, easy to use, and performant for building, parsing, and iterating BSON data.

Where is the MongoDB Go Driver

The MongoDB Go Driver is available from Github and the documentation is available from the MongoDB Documentation site as well as GoDoc.

How to use the MongoDB Go Driver

If you are not migrating from mgo or another community driver you can get started by reviewing the docs and examples, or by reading this tutorial.

If you are migrating from mgo or another community driver, read further to understand some of the considerations when migrating.

What is involved in migrating from a community driver to the MongoDB Go Driver.

Users who have previously connected to MongoDB from applications written in Go have used various client libraries/packages to enable database connectivity. In order to move to the MongoDB Go Driver, the client application must depend on different packages and change certain programmatic calls to those packages.

Advice for Migration

Assessing size and impact of changes.

Locating code points for migration

Start by establishing the locations of all code that relies on your previous Go/MongoDB driver. For example, locate all lines in the code which match mgo, bson, txn or mongo and then scan forward from those locations for further use of the driver. This code will need to be changed as part of the migration.

Using Extended JSON

Consider moving code that uses mgo’s Extended JSON to MongoDB Go drivers Extended JSON implementation (*ExtJSON* functions).

Tests

Tests may require changes to new packages and functions. Once tests are migrated to new APIs, results may help to indicate where further changes beyond driver API calls are required to ensure that application behavior and performance are not affected by the migration.

APIs and functions in community libraries that are not supported or have modified interfaces or behaviors in MongoDB Go Driver

General Changes

Support for MongoDB server versions prior to 3.2 is not available in the MongoDB Go Driver during early BETA releases. Consider delaying migration until BETA 2 is released.

MongoDB Go Driver connection strings are the most direct and convenient way to configure the client connection. Consider client Options for more complex configuration needs.

BSON Changes

Moving from the mgo bson package to the MongoDB Go Driver bson package will require type changes and some types have moved from the bson package to primitive package. bson.D and bson.M are unchanged but most other types require some further consideration during migration.

Changing from mgo.Session to mongo.Client

mgo.Session

  • session.Run() runs a command on the admin database, and optionally takes a string for {: 1} style commands. Consider using a common helper to Run() and RunString() helpers on SessionProvider.
  • mongo.Client doesn't support changing the socket timeout after construction (as in SetSocketTimeout(0) ). Customize the socket timeout via a URI option.
  • SetPrefetch is an mgo cursor optimization not available in the MongoDB Go driver; instead, the future implementation of exhaust support for OP_MSG should be used when available.
  • SetSafe is irrelevant as the MongoDB Go driver defaults to safe operation
  • SetMode in mgo can be used for emulating a direct connection; this will need to be replaced with configuration for a direct connection instead.
  • Copy is used for collection cloning; the MongoDB Go driver does this internally
  • session.Create() has no equivalent in the MongoDB Go driver but is trivially replaceable with RunCommand.
  • session.Close() should not be called in the MongoDB Go client unless you want to close/disconnect the common mongo.Client.

One of the most common usage patterns in mgo is `session.DB("foo").C("bar")`. This can be changed easily with text editing tools and regular expressions, such as in VIM:

    
        :%s/\vsession\.DB\(([^\)]+)\).C\(([^\)]+)\)/client.Database(\1).Collection(\2)/cg
   

CRUD changes

  • Repair() method is not available.
  • mgo's cursor iterator has an "All" method to populate a slice of results. Loop or iterate in the MongoDB Go Driver.
  • mgo custom dialer "Connection" types were unnecessary and removed, along with build-flags for 'ssl' and 'sasl' -- the MongoDB Go driver supports these directly.
  • mgo's API for Sort takes strings with possible '-' prefix. Those need to be converted to a proper sort document for use with the MongoDB Go driver.
  • mgo's Index model is very different than the Go driver's implementation, so you may need to change a lot of code that otherwise expects certain options fields into lookups, or you have to copy the type and inflate into it.

Config Changes

  • mgo allows setting a Kerberos "ServiceHost" -- a host name for SASL auth that is different than the connection host name. The MongoDB Go driver has no equivalent (nor does the auth spec).
  • mgo supports deferred Find query, later calling Count,Iter, or other modifiers on it as needed. This concept doesn't exist in the MongoDB Go driver and needs to be emulated.
    • Consider a common library to hold filter, hint options and emulate Iter() and Count()
    • Examples:
                  
      mgo.Collection.Find(...).Hint(...)
      // mgo.Collection
      cursor = coll.Find(filter).Hint(doc).Iter()
      <p>// mongo.Collection
      cursor, err = coll.Find(nil, filter, findopt.Hint(doc))
      
      
      
      mgo.Collection.Find(...).One(...) translation
      // mgo.Collection
      err = coll.Find(filter).One(&doc)</p>
      <p>// mongo.Collection
      result = coll.FindOne(nil, filter)
      err = result.Decode(&doc)
      
      
  • Cursor iteration (N.B. tools often don't call iter.Close())
  •     
    // mgo.Iter
    var result resultType{}
    for iter.Next(&result) {
        // ... do stuff with result ...
    }
    if err := iter.Close(); err != nil {
        return err
    }
    <p>// mongo.Cursor (requires non-nil context until GODRIVER-579 is done)
    ctx := context.Background()
    defer cur.Close(ctx)
    for cur.Next(ctx) {
    result := resultType{}
    if err := cur.Decode(&result); err != nil {
    // ...
    }
    // ... do stuff with result ...
    }
    if err := cur.Err(); err != nil {
    // ...
    }
    
    

Ongoing Development and Feedback

As a beta release, the MongoDB Go Driver is under active development and as such, some features and functions available in community drivers or previous driver versions may not be available. Please file requests for missing features or any other issues you discover as part of your migration. You can also find support and guidance by joining and posting to the MongoDB Go Driver mailing list.