diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/batch_cursor.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/batch_cursor.go
new file mode 100644
index 0000000..a7ce0b5
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/batch_cursor.go
@@ -0,0 +1,30 @@
+package mongo
+
+import (
+	"context"
+)
+
+// batchCursor is the interface implemented by types that can provide batches of document results.
+// The Cursor type is built on top of this type.
+type batchCursor interface {
+	// ID returns the ID of the cursor.
+	ID() int64
+
+	// Next returns true if there is a batch available.
+	Next(context.Context) bool
+
+	// Batch appends the current batch of documents to dst. RequiredBytes can be used to determine
+	// the length of the current batch of documents.
+	//
+	// If there is no batch available, this method should do nothing.
+	Batch(dst []byte) []byte
+
+	// RequiredBytes returns the number of bytes required fo rthe current batch.
+	RequiredBytes() int
+
+	// Err returns the last error encountered.
+	Err() error
+
+	// Close closes the cursor.
+	Close(context.Context) error
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/bulk_write.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/bulk_write.go
new file mode 100644
index 0000000..f086189
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/bulk_write.go
@@ -0,0 +1,341 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+)
+
+// WriteModel is the interface satisfied by all models for bulk writes.
+type WriteModel interface {
+	convertModel() driver.WriteModel
+}
+
+// InsertOneModel is the write model for insert operations.
+type InsertOneModel struct {
+	Document interface{}
+}
+
+// NewInsertOneModel creates a new InsertOneModel.
+func NewInsertOneModel() *InsertOneModel {
+	return &InsertOneModel{}
+}
+
+// SetDocument sets the BSON document for the InsertOneModel.
+func (iom *InsertOneModel) SetDocument(doc interface{}) *InsertOneModel {
+	iom.Document = doc
+	return iom
+}
+
+func (iom *InsertOneModel) convertModel() driver.WriteModel {
+	return driver.InsertOneModel{
+		Document: iom.Document,
+	}
+}
+
+// DeleteOneModel is the write model for delete operations.
+type DeleteOneModel struct {
+	Filter    interface{}
+	Collation *options.Collation
+}
+
+// NewDeleteOneModel creates a new DeleteOneModel.
+func NewDeleteOneModel() *DeleteOneModel {
+	return &DeleteOneModel{}
+}
+
+// SetFilter sets the filter for the DeleteOneModel.
+func (dom *DeleteOneModel) SetFilter(filter interface{}) *DeleteOneModel {
+	dom.Filter = filter
+	return dom
+}
+
+// SetCollation sets the collation for the DeleteOneModel.
+func (dom *DeleteOneModel) SetCollation(collation *options.Collation) *DeleteOneModel {
+	dom.Collation = collation
+	return dom
+}
+
+func (dom *DeleteOneModel) convertModel() driver.WriteModel {
+	return driver.DeleteOneModel{
+		Collation: dom.Collation,
+		Filter:    dom.Filter,
+	}
+}
+
+// DeleteManyModel is the write model for deleteMany operations.
+type DeleteManyModel struct {
+	Filter    interface{}
+	Collation *options.Collation
+}
+
+// NewDeleteManyModel creates a new DeleteManyModel.
+func NewDeleteManyModel() *DeleteManyModel {
+	return &DeleteManyModel{}
+}
+
+// SetFilter sets the filter for the DeleteManyModel.
+func (dmm *DeleteManyModel) SetFilter(filter interface{}) *DeleteManyModel {
+	dmm.Filter = filter
+	return dmm
+}
+
+// SetCollation sets the collation for the DeleteManyModel.
+func (dmm *DeleteManyModel) SetCollation(collation *options.Collation) *DeleteManyModel {
+	dmm.Collation = collation
+	return dmm
+}
+
+func (dmm *DeleteManyModel) convertModel() driver.WriteModel {
+	return driver.DeleteManyModel{
+		Collation: dmm.Collation,
+		Filter:    dmm.Filter,
+	}
+}
+
+// ReplaceOneModel is the write model for replace operations.
+type ReplaceOneModel struct {
+	Collation   *options.Collation
+	Upsert      *bool
+	Filter      interface{}
+	Replacement interface{}
+}
+
+// NewReplaceOneModel creates a new ReplaceOneModel.
+func NewReplaceOneModel() *ReplaceOneModel {
+	return &ReplaceOneModel{}
+}
+
+// SetFilter sets the filter for the ReplaceOneModel.
+func (rom *ReplaceOneModel) SetFilter(filter interface{}) *ReplaceOneModel {
+	rom.Filter = filter
+	return rom
+}
+
+// SetReplacement sets the replacement document for the ReplaceOneModel.
+func (rom *ReplaceOneModel) SetReplacement(rep interface{}) *ReplaceOneModel {
+	rom.Replacement = rep
+	return rom
+}
+
+// SetCollation sets the collation for the ReplaceOneModel.
+func (rom *ReplaceOneModel) SetCollation(collation *options.Collation) *ReplaceOneModel {
+	rom.Collation = collation
+	return rom
+}
+
+// SetUpsert specifies if a new document should be created if no document matches the query.
+func (rom *ReplaceOneModel) SetUpsert(upsert bool) *ReplaceOneModel {
+	rom.Upsert = &upsert
+	return rom
+}
+
+func (rom *ReplaceOneModel) convertModel() driver.WriteModel {
+	um := driver.UpdateModel{
+		Collation: rom.Collation,
+	}
+	if rom.Upsert != nil {
+		um.Upsert = *rom.Upsert
+		um.UpsertSet = true
+	}
+
+	return driver.ReplaceOneModel{
+		UpdateModel: um,
+		Filter:      rom.Filter,
+		Replacement: rom.Replacement,
+	}
+}
+
+// UpdateOneModel is the write model for update operations.
+type UpdateOneModel struct {
+	Collation    *options.Collation
+	Upsert       *bool
+	Filter       interface{}
+	Update       interface{}
+	ArrayFilters *options.ArrayFilters
+}
+
+// NewUpdateOneModel creates a new UpdateOneModel.
+func NewUpdateOneModel() *UpdateOneModel {
+	return &UpdateOneModel{}
+}
+
+// SetFilter sets the filter for the UpdateOneModel.
+func (uom *UpdateOneModel) SetFilter(filter interface{}) *UpdateOneModel {
+	uom.Filter = filter
+	return uom
+}
+
+// SetUpdate sets the update document for the UpdateOneModel.
+func (uom *UpdateOneModel) SetUpdate(update interface{}) *UpdateOneModel {
+	uom.Update = update
+	return uom
+}
+
+// SetArrayFilters specifies a set of filters specifying to which array elements an update should apply.
+func (uom *UpdateOneModel) SetArrayFilters(filters options.ArrayFilters) *UpdateOneModel {
+	uom.ArrayFilters = &filters
+	return uom
+}
+
+// SetCollation sets the collation for the UpdateOneModel.
+func (uom *UpdateOneModel) SetCollation(collation *options.Collation) *UpdateOneModel {
+	uom.Collation = collation
+	return uom
+}
+
+// SetUpsert specifies if a new document should be created if no document matches the query.
+func (uom *UpdateOneModel) SetUpsert(upsert bool) *UpdateOneModel {
+	uom.Upsert = &upsert
+	return uom
+}
+
+func (uom *UpdateOneModel) convertModel() driver.WriteModel {
+	um := driver.UpdateModel{
+		Collation: uom.Collation,
+	}
+	if uom.Upsert != nil {
+		um.Upsert = *uom.Upsert
+		um.UpsertSet = true
+	}
+
+	converted := driver.UpdateOneModel{
+		UpdateModel: um,
+		Filter:      uom.Filter,
+		Update:      uom.Update,
+	}
+	if uom.ArrayFilters != nil {
+		converted.ArrayFilters = *uom.ArrayFilters
+		converted.ArrayFiltersSet = true
+	}
+
+	return converted
+}
+
+// UpdateManyModel is the write model for updateMany operations.
+type UpdateManyModel struct {
+	Collation    *options.Collation
+	Upsert       *bool
+	Filter       interface{}
+	Update       interface{}
+	ArrayFilters *options.ArrayFilters
+}
+
+// NewUpdateManyModel creates a new UpdateManyModel.
+func NewUpdateManyModel() *UpdateManyModel {
+	return &UpdateManyModel{}
+}
+
+// SetFilter sets the filter for the UpdateManyModel.
+func (umm *UpdateManyModel) SetFilter(filter interface{}) *UpdateManyModel {
+	umm.Filter = filter
+	return umm
+}
+
+// SetUpdate sets the update document for the UpdateManyModel.
+func (umm *UpdateManyModel) SetUpdate(update interface{}) *UpdateManyModel {
+	umm.Update = update
+	return umm
+}
+
+// SetArrayFilters specifies a set of filters specifying to which array elements an update should apply.
+func (umm *UpdateManyModel) SetArrayFilters(filters options.ArrayFilters) *UpdateManyModel {
+	umm.ArrayFilters = &filters
+	return umm
+}
+
+// SetCollation sets the collation for the UpdateManyModel.
+func (umm *UpdateManyModel) SetCollation(collation *options.Collation) *UpdateManyModel {
+	umm.Collation = collation
+	return umm
+}
+
+// SetUpsert specifies if a new document should be created if no document matches the query.
+func (umm *UpdateManyModel) SetUpsert(upsert bool) *UpdateManyModel {
+	umm.Upsert = &upsert
+	return umm
+}
+
+func (umm *UpdateManyModel) convertModel() driver.WriteModel {
+	um := driver.UpdateModel{
+		Collation: umm.Collation,
+	}
+	if umm.Upsert != nil {
+		um.Upsert = *umm.Upsert
+		um.UpsertSet = true
+	}
+
+	converted := driver.UpdateManyModel{
+		UpdateModel: um,
+		Filter:      umm.Filter,
+		Update:      umm.Update,
+	}
+	if umm.ArrayFilters != nil {
+		converted.ArrayFilters = *umm.ArrayFilters
+		converted.ArrayFiltersSet = true
+	}
+
+	return converted
+}
+
+func dispatchToMongoModel(model driver.WriteModel) WriteModel {
+	switch conv := model.(type) {
+	case driver.InsertOneModel:
+		return &InsertOneModel{
+			Document: conv.Document,
+		}
+	case driver.DeleteOneModel:
+		return &DeleteOneModel{
+			Filter:    conv.Filter,
+			Collation: conv.Collation,
+		}
+	case driver.DeleteManyModel:
+		return &DeleteManyModel{
+			Filter:    conv.Filter,
+			Collation: conv.Collation,
+		}
+	case driver.ReplaceOneModel:
+		rom := &ReplaceOneModel{
+			Filter:      conv.Filter,
+			Replacement: conv.Replacement,
+			Collation:   conv.Collation,
+		}
+		if conv.UpsertSet {
+			rom.Upsert = &conv.Upsert
+		}
+		return rom
+	case driver.UpdateOneModel:
+		uom := &UpdateOneModel{
+			Filter:    conv.Filter,
+			Update:    conv.Update,
+			Collation: conv.Collation,
+		}
+		if conv.UpsertSet {
+			uom.Upsert = &conv.Upsert
+		}
+		if conv.ArrayFiltersSet {
+			uom.ArrayFilters = &conv.ArrayFilters
+		}
+		return uom
+	case driver.UpdateManyModel:
+		umm := &UpdateManyModel{
+			Filter:    conv.Filter,
+			Update:    conv.Update,
+			Collation: conv.Collation,
+		}
+		if conv.UpsertSet {
+			umm.Upsert = &conv.Upsert
+		}
+		if conv.ArrayFiltersSet {
+			umm.ArrayFilters = &conv.ArrayFilters
+		}
+		return umm
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/change_stream.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/change_stream.go
new file mode 100644
index 0000000..5330117
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/change_stream.go
@@ -0,0 +1,508 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"errors"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/x/bsonx"
+	"github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/description"
+)
+
+const errorInterrupted int32 = 11601
+const errorCappedPositionLost int32 = 136
+const errorCursorKilled int32 = 237
+
+// ErrMissingResumeToken indicates that a change stream notification from the server did not
+// contain a resume token.
+var ErrMissingResumeToken = errors.New("cannot provide resume functionality when the resume token is missing")
+
+// ErrNilCursor indicates that the cursor for the change stream is nil.
+var ErrNilCursor = errors.New("cursor is nil")
+
+// ChangeStream instances iterate a stream of change documents. Each document can be decoded via the
+// Decode method. Resume tokens should be retrieved via the ResumeToken method and can be stored to
+// resume the change stream at a specific point in time.
+//
+// A typical usage of the ChangeStream type would be:
+type ChangeStream struct {
+	// Current is the BSON bytes of the current change document. This property is only valid until
+	// the next call to Next or Close. If continued access is required to the bson.Raw, you must
+	// make a copy of it.
+	Current bson.Raw
+
+	cmd        bsonx.Doc // aggregate command to run to create stream and rebuild cursor
+	pipeline   bsonx.Arr
+	options    *options.ChangeStreamOptions
+	coll       *Collection
+	db         *Database
+	ns         command.Namespace
+	cursor     *Cursor
+	cursorOpts bsonx.Doc
+
+	resumeToken bsonx.Doc
+	err         error
+	streamType  StreamType
+	client      *Client
+	sess        Session
+	readPref    *readpref.ReadPref
+	readConcern *readconcern.ReadConcern
+	registry    *bsoncodec.Registry
+}
+
+func (cs *ChangeStream) replaceOptions(desc description.SelectedServer) {
+	// if cs has not received any changes and resumeAfter not specified and max wire version >= 7, run known agg cmd
+	// with startAtOperationTime set to startAtOperationTime provided by user or saved from initial agg
+	// must not send resumeAfter key
+
+	// else: run known agg cmd with resumeAfter set to last known resumeToken
+	// must not set startAtOperationTime (remove if originally in cmd)
+
+	if cs.options.ResumeAfter == nil && desc.WireVersion.Max >= 7 && cs.resumeToken == nil {
+		cs.options.SetStartAtOperationTime(cs.sess.OperationTime())
+	} else {
+		if cs.resumeToken == nil {
+			return // restart stream without the resume token
+		}
+
+		cs.options.SetResumeAfter(cs.resumeToken)
+		// remove startAtOperationTime
+		cs.options.SetStartAtOperationTime(nil)
+	}
+}
+
+// Create options docs for the pipeline and cursor
+func createCmdDocs(csType StreamType, opts *options.ChangeStreamOptions, registry *bsoncodec.Registry) (bsonx.Doc,
+	bsonx.Doc, bsonx.Doc, error) {
+
+	pipelineDoc := bsonx.Doc{}
+	cursorDoc := bsonx.Doc{}
+	optsDoc := bsonx.Doc{}
+
+	if csType == ClientStream {
+		pipelineDoc = pipelineDoc.Append("allChangesForCluster", bsonx.Boolean(true))
+	}
+
+	if opts.BatchSize != nil {
+		cursorDoc = cursorDoc.Append("batchSize", bsonx.Int32(*opts.BatchSize))
+	}
+	if opts.Collation != nil {
+		optsDoc = optsDoc.Append("collation", bsonx.Document(opts.Collation.ToDocument()))
+	}
+	if opts.FullDocument != nil {
+		pipelineDoc = pipelineDoc.Append("fullDocument", bsonx.String(string(*opts.FullDocument)))
+	}
+	if opts.MaxAwaitTime != nil {
+		ms := int64(time.Duration(*opts.MaxAwaitTime) / time.Millisecond)
+		pipelineDoc = pipelineDoc.Append("maxAwaitTimeMS", bsonx.Int64(ms))
+	}
+	if opts.ResumeAfter != nil {
+		rt, err := transformDocument(registry, opts.ResumeAfter)
+		if err != nil {
+			return nil, nil, nil, err
+		}
+
+		pipelineDoc = pipelineDoc.Append("resumeAfter", bsonx.Document(rt))
+	}
+	if opts.StartAtOperationTime != nil {
+		pipelineDoc = pipelineDoc.Append("startAtOperationTime",
+			bsonx.Timestamp(opts.StartAtOperationTime.T, opts.StartAtOperationTime.I))
+	}
+
+	return pipelineDoc, cursorDoc, optsDoc, nil
+}
+
+func getSession(ctx context.Context, client *Client) (Session, error) {
+	sess := sessionFromContext(ctx)
+	if err := client.ValidSession(sess); err != nil {
+		return nil, err
+	}
+
+	var mongoSess Session
+	if sess != nil {
+		mongoSess = &sessionImpl{
+			Client: sess,
+		}
+	} else {
+		// create implicit session because it will be needed
+		newSess, err := session.NewClientSession(client.topology.SessionPool, client.id, session.Implicit)
+		if err != nil {
+			return nil, err
+		}
+
+		mongoSess = &sessionImpl{
+			Client: newSess,
+		}
+	}
+
+	return mongoSess, nil
+}
+
+func parseOptions(csType StreamType, opts *options.ChangeStreamOptions, registry *bsoncodec.Registry) (bsonx.Doc,
+	bsonx.Doc, bsonx.Doc, error) {
+
+	if opts.FullDocument == nil {
+		opts = opts.SetFullDocument(options.Default)
+	}
+
+	pipelineDoc, cursorDoc, optsDoc, err := createCmdDocs(csType, opts, registry)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+
+	return pipelineDoc, cursorDoc, optsDoc, nil
+}
+
+func (cs *ChangeStream) runCommand(ctx context.Context, replaceOptions bool) error {
+	ss, err := cs.client.topology.SelectServer(ctx, cs.db.writeSelector)
+	if err != nil {
+		return err
+	}
+
+	desc := ss.Description()
+	conn, err := ss.Connection(ctx)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	if replaceOptions {
+		cs.replaceOptions(desc)
+		optionsDoc, _, _, err := createCmdDocs(cs.streamType, cs.options, cs.registry)
+		if err != nil {
+			return err
+		}
+
+		changeStreamDoc := bsonx.Doc{
+			{"$changeStream", bsonx.Document(optionsDoc)},
+		}
+		cs.pipeline[0] = bsonx.Document(changeStreamDoc)
+		cs.cmd.Set("pipeline", bsonx.Array(cs.pipeline))
+	}
+
+	readCmd := command.Read{
+		DB:          cs.db.name,
+		Command:     cs.cmd,
+		Session:     cs.sess.(*sessionImpl).Client,
+		Clock:       cs.client.clock,
+		ReadPref:    cs.readPref,
+		ReadConcern: cs.readConcern,
+	}
+
+	rdr, err := readCmd.RoundTrip(ctx, desc, conn)
+	if err != nil {
+		cs.sess.EndSession(ctx)
+		return err
+	}
+
+	batchCursor, err := driver.NewBatchCursor(bsoncore.Document(rdr), readCmd.Session, readCmd.Clock, ss.Server)
+	if err != nil {
+		cs.sess.EndSession(ctx)
+		return err
+	}
+	cursor, err := newCursor(batchCursor, cs.registry)
+	if err != nil {
+		cs.sess.EndSession(ctx)
+		return err
+	}
+	cs.cursor = cursor
+
+	cursorValue, err := rdr.LookupErr("cursor")
+	if err != nil {
+		return err
+	}
+	cursorDoc := cursorValue.Document()
+	cs.ns = command.ParseNamespace(cursorDoc.Lookup("ns").StringValue())
+
+	return nil
+}
+
+func newChangeStream(ctx context.Context, coll *Collection, pipeline interface{},
+	opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+
+	pipelineArr, err := transformAggregatePipeline(coll.registry, pipeline)
+	if err != nil {
+		return nil, err
+	}
+
+	csOpts := options.MergeChangeStreamOptions(opts...)
+	pipelineDoc, cursorDoc, optsDoc, err := parseOptions(CollectionStream, csOpts, coll.registry)
+	if err != nil {
+		return nil, err
+	}
+	sess, err := getSession(ctx, coll.client)
+	if err != nil {
+		return nil, err
+	}
+
+	csDoc := bsonx.Document(bsonx.Doc{
+		{"$changeStream", bsonx.Document(pipelineDoc)},
+	})
+	pipelineArr = append(bsonx.Arr{csDoc}, pipelineArr...)
+
+	cmd := bsonx.Doc{
+		{"aggregate", bsonx.String(coll.name)},
+		{"pipeline", bsonx.Array(pipelineArr)},
+		{"cursor", bsonx.Document(cursorDoc)},
+	}
+	cmd = append(cmd, optsDoc...)
+
+	cs := &ChangeStream{
+		client:      coll.client,
+		sess:        sess,
+		cmd:         cmd,
+		pipeline:    pipelineArr,
+		coll:        coll,
+		db:          coll.db,
+		streamType:  CollectionStream,
+		readPref:    coll.readPreference,
+		readConcern: coll.readConcern,
+		options:     csOpts,
+		registry:    coll.registry,
+		cursorOpts:  cursorDoc,
+	}
+
+	err = cs.runCommand(ctx, false)
+	if err != nil {
+		return nil, err
+	}
+
+	return cs, nil
+}
+
+func newDbChangeStream(ctx context.Context, db *Database, pipeline interface{},
+	opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+
+	pipelineArr, err := transformAggregatePipeline(db.registry, pipeline)
+	if err != nil {
+		return nil, err
+	}
+
+	csOpts := options.MergeChangeStreamOptions(opts...)
+	pipelineDoc, cursorDoc, optsDoc, err := parseOptions(DatabaseStream, csOpts, db.registry)
+	if err != nil {
+		return nil, err
+	}
+	sess, err := getSession(ctx, db.client)
+	if err != nil {
+		return nil, err
+	}
+
+	csDoc := bsonx.Document(bsonx.Doc{
+		{"$changeStream", bsonx.Document(pipelineDoc)},
+	})
+	pipelineArr = append(bsonx.Arr{csDoc}, pipelineArr...)
+
+	cmd := bsonx.Doc{
+		{"aggregate", bsonx.Int32(1)},
+		{"pipeline", bsonx.Array(pipelineArr)},
+		{"cursor", bsonx.Document(cursorDoc)},
+	}
+	cmd = append(cmd, optsDoc...)
+
+	cs := &ChangeStream{
+		client:      db.client,
+		db:          db,
+		sess:        sess,
+		cmd:         cmd,
+		pipeline:    pipelineArr,
+		streamType:  DatabaseStream,
+		readPref:    db.readPreference,
+		readConcern: db.readConcern,
+		options:     csOpts,
+		registry:    db.registry,
+		cursorOpts:  cursorDoc,
+	}
+
+	err = cs.runCommand(ctx, false)
+	if err != nil {
+		return nil, err
+	}
+
+	return cs, nil
+}
+
+func newClientChangeStream(ctx context.Context, client *Client, pipeline interface{},
+	opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+
+	pipelineArr, err := transformAggregatePipeline(client.registry, pipeline)
+	if err != nil {
+		return nil, err
+	}
+
+	csOpts := options.MergeChangeStreamOptions(opts...)
+	pipelineDoc, cursorDoc, optsDoc, err := parseOptions(ClientStream, csOpts, client.registry)
+	if err != nil {
+		return nil, err
+	}
+	sess, err := getSession(ctx, client)
+	if err != nil {
+		return nil, err
+	}
+
+	csDoc := bsonx.Document(bsonx.Doc{
+		{"$changeStream", bsonx.Document(pipelineDoc)},
+	})
+	pipelineArr = append(bsonx.Arr{csDoc}, pipelineArr...)
+
+	cmd := bsonx.Doc{
+		{"aggregate", bsonx.Int32(1)},
+		{"pipeline", bsonx.Array(pipelineArr)},
+		{"cursor", bsonx.Document(cursorDoc)},
+	}
+	cmd = append(cmd, optsDoc...)
+
+	cs := &ChangeStream{
+		client:      client,
+		db:          client.Database("admin"),
+		sess:        sess,
+		cmd:         cmd,
+		pipeline:    pipelineArr,
+		streamType:  ClientStream,
+		readPref:    client.readPreference,
+		readConcern: client.readConcern,
+		options:     csOpts,
+		registry:    client.registry,
+		cursorOpts:  cursorDoc,
+	}
+
+	err = cs.runCommand(ctx, false)
+	if err != nil {
+		return nil, err
+	}
+
+	return cs, nil
+}
+
+func (cs *ChangeStream) storeResumeToken() error {
+	idVal, err := cs.cursor.Current.LookupErr("_id")
+	if err != nil {
+		_ = cs.Close(context.Background())
+		return ErrMissingResumeToken
+	}
+
+	var idDoc bson.Raw
+	idDoc, ok := idVal.DocumentOK()
+	if !ok {
+		_ = cs.Close(context.Background())
+		return ErrMissingResumeToken
+	}
+	tokenDoc, err := bsonx.ReadDoc(idDoc)
+	if err != nil {
+		_ = cs.Close(context.Background())
+		return ErrMissingResumeToken
+	}
+
+	cs.resumeToken = tokenDoc
+	return nil
+}
+
+// ID returns the cursor ID for this change stream.
+func (cs *ChangeStream) ID() int64 {
+	if cs.cursor == nil {
+		return 0
+	}
+
+	return cs.cursor.ID()
+}
+
+// Next gets the next result from this change stream. Returns true if there were no errors and the next
+// result is available for decoding.
+func (cs *ChangeStream) Next(ctx context.Context) bool {
+	// execute in a loop to retry resume-able errors and advance the underlying cursor
+	for {
+		if cs.cursor == nil {
+			return false
+		}
+
+		if cs.cursor.Next(ctx) {
+			err := cs.storeResumeToken()
+			if err != nil {
+				cs.err = err
+				return false
+			}
+
+			cs.Current = cs.cursor.Current
+			return true
+		}
+
+		err := cs.cursor.Err()
+		if err == nil {
+			return false
+		}
+
+		switch t := err.(type) {
+		case command.Error:
+			if t.Code == errorInterrupted || t.Code == errorCappedPositionLost || t.Code == errorCursorKilled {
+				return false
+			}
+		}
+
+		killCursors := command.KillCursors{
+			NS:  cs.ns,
+			IDs: []int64{cs.ID()},
+		}
+
+		_, _ = driver.KillCursors(ctx, killCursors, cs.client.topology, cs.db.writeSelector)
+		cs.err = cs.runCommand(ctx, true)
+		if cs.err != nil {
+			return false
+		}
+	}
+}
+
+// Decode will decode the current document into val.
+func (cs *ChangeStream) Decode(out interface{}) error {
+	if cs.cursor == nil {
+		return ErrNilCursor
+	}
+
+	return bson.UnmarshalWithRegistry(cs.registry, cs.Current, out)
+}
+
+// Err returns the current error.
+func (cs *ChangeStream) Err() error {
+	if cs.err != nil {
+		return cs.err
+	}
+	if cs.cursor == nil {
+		return nil
+	}
+
+	return cs.cursor.Err()
+}
+
+// Close closes this cursor.
+func (cs *ChangeStream) Close(ctx context.Context) error {
+	if cs.cursor == nil {
+		return nil // cursor is already closed
+	}
+
+	return cs.cursor.Close(ctx)
+}
+
+// StreamType represents the type of a change stream.
+type StreamType uint8
+
+// These constants represent valid change stream types. A change stream can be initialized over a collection, all
+// collections in a database, or over a whole client.
+const (
+	CollectionStream StreamType = iota
+	DatabaseStream
+	ClientStream
+)
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/client.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/client.go
new file mode 100644
index 0000000..7984bc0
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/client.go
@@ -0,0 +1,454 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+	"github.com/mongodb/mongo-go-driver/tag"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/uuid"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/connstring"
+	"github.com/mongodb/mongo-go-driver/x/network/description"
+)
+
+const defaultLocalThreshold = 15 * time.Millisecond
+
+// Client performs operations on a given topology.
+type Client struct {
+	id              uuid.UUID
+	topologyOptions []topology.Option
+	topology        *topology.Topology
+	connString      connstring.ConnString
+	localThreshold  time.Duration
+	retryWrites     bool
+	clock           *session.ClusterClock
+	readPreference  *readpref.ReadPref
+	readConcern     *readconcern.ReadConcern
+	writeConcern    *writeconcern.WriteConcern
+	registry        *bsoncodec.Registry
+	marshaller      BSONAppender
+}
+
+// Connect creates a new Client and then initializes it using the Connect method.
+func Connect(ctx context.Context, uri string, opts ...*options.ClientOptions) (*Client, error) {
+	c, err := NewClientWithOptions(uri, opts...)
+	if err != nil {
+		return nil, err
+	}
+	err = c.Connect(ctx)
+	if err != nil {
+		return nil, err
+	}
+	return c, nil
+}
+
+// NewClient creates a new client to connect to a cluster specified by the uri.
+func NewClient(uri string) (*Client, error) {
+	cs, err := connstring.Parse(uri)
+	if err != nil {
+		return nil, err
+	}
+
+	return newClient(cs)
+}
+
+// NewClientWithOptions creates a new client to connect to to a cluster specified by the connection
+// string and the options manually passed in. If the same option is configured in both the
+// connection string and the manual options, the manual option will be ignored.
+func NewClientWithOptions(uri string, opts ...*options.ClientOptions) (*Client, error) {
+	cs, err := connstring.Parse(uri)
+	if err != nil {
+		return nil, err
+	}
+
+	return newClient(cs, opts...)
+}
+
+// Connect initializes the Client by starting background monitoring goroutines.
+// This method must be called before a Client can be used.
+func (c *Client) Connect(ctx context.Context) error {
+	err := c.topology.Connect(ctx)
+	if err != nil {
+		return replaceTopologyErr(err)
+	}
+
+	return nil
+
+}
+
+// Disconnect closes sockets to the topology referenced by this Client. It will
+// shut down any monitoring goroutines, close the idle connection pool, and will
+// wait until all the in use connections have been returned to the connection
+// pool and closed before returning. If the context expires via cancellation,
+// deadline, or timeout before the in use connections have returned, the in use
+// connections will be closed, resulting in the failure of any in flight read
+// or write operations. If this method returns with no errors, all connections
+// associated with this Client have been closed.
+func (c *Client) Disconnect(ctx context.Context) error {
+	c.endSessions(ctx)
+	return replaceTopologyErr(c.topology.Disconnect(ctx))
+}
+
+// Ping verifies that the client can connect to the topology.
+// If readPreference is nil then will use the client's default read
+// preference.
+func (c *Client) Ping(ctx context.Context, rp *readpref.ReadPref) error {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	if rp == nil {
+		rp = c.readPreference
+	}
+
+	_, err := c.topology.SelectServer(ctx, description.ReadPrefSelector(rp))
+	return replaceTopologyErr(err)
+}
+
+// StartSession starts a new session.
+func (c *Client) StartSession(opts ...*options.SessionOptions) (Session, error) {
+	if c.topology.SessionPool == nil {
+		return nil, ErrClientDisconnected
+	}
+
+	sopts := options.MergeSessionOptions(opts...)
+	coreOpts := &session.ClientOptions{
+		DefaultReadConcern:    c.readConcern,
+		DefaultReadPreference: c.readPreference,
+		DefaultWriteConcern:   c.writeConcern,
+	}
+	if sopts.CausalConsistency != nil {
+		coreOpts.CausalConsistency = sopts.CausalConsistency
+	}
+	if sopts.DefaultReadConcern != nil {
+		coreOpts.DefaultReadConcern = sopts.DefaultReadConcern
+	}
+	if sopts.DefaultWriteConcern != nil {
+		coreOpts.DefaultWriteConcern = sopts.DefaultWriteConcern
+	}
+	if sopts.DefaultReadPreference != nil {
+		coreOpts.DefaultReadPreference = sopts.DefaultReadPreference
+	}
+
+	sess, err := session.NewClientSession(c.topology.SessionPool, c.id, session.Explicit, coreOpts)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+
+	sess.RetryWrite = c.retryWrites
+
+	return &sessionImpl{
+		Client: sess,
+		topo:   c.topology,
+	}, nil
+}
+
+func (c *Client) endSessions(ctx context.Context) {
+	if c.topology.SessionPool == nil {
+		return
+	}
+	cmd := command.EndSessions{
+		Clock:      c.clock,
+		SessionIDs: c.topology.SessionPool.IDSlice(),
+	}
+
+	_, _ = driver.EndSessions(ctx, cmd, c.topology, description.ReadPrefSelector(readpref.PrimaryPreferred()))
+}
+
+func newClient(cs connstring.ConnString, opts ...*options.ClientOptions) (*Client, error) {
+	clientOpt := options.MergeClientOptions(cs, opts...)
+
+	client := &Client{
+		topologyOptions: clientOpt.TopologyOptions,
+		connString:      clientOpt.ConnString,
+		localThreshold:  defaultLocalThreshold,
+		readPreference:  clientOpt.ReadPreference,
+		readConcern:     clientOpt.ReadConcern,
+		writeConcern:    clientOpt.WriteConcern,
+		registry:        clientOpt.Registry,
+	}
+
+	if client.connString.RetryWritesSet {
+		client.retryWrites = client.connString.RetryWrites
+	}
+	if clientOpt.RetryWrites != nil {
+		client.retryWrites = *clientOpt.RetryWrites
+	}
+
+	clientID, err := uuid.New()
+	if err != nil {
+		return nil, err
+	}
+	client.id = clientID
+
+	topts := append(
+		client.topologyOptions,
+		topology.WithConnString(func(connstring.ConnString) connstring.ConnString { return client.connString }),
+		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
+			return append(opts, topology.WithClock(func(clock *session.ClusterClock) *session.ClusterClock {
+				return client.clock
+			}), topology.WithRegistry(func(registry *bsoncodec.Registry) *bsoncodec.Registry {
+				return client.registry
+			}))
+		}),
+	)
+	topo, err := topology.New(topts...)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+	client.topology = topo
+	client.clock = &session.ClusterClock{}
+
+	if client.readConcern == nil {
+		client.readConcern = readConcernFromConnString(&client.connString)
+
+		if client.readConcern == nil {
+			// no read concern in conn string
+			client.readConcern = readconcern.New()
+		}
+	}
+
+	if client.writeConcern == nil {
+		client.writeConcern = writeConcernFromConnString(&client.connString)
+	}
+	if client.readPreference == nil {
+		rp, err := readPreferenceFromConnString(&client.connString)
+		if err != nil {
+			return nil, err
+		}
+		if rp != nil {
+			client.readPreference = rp
+		} else {
+			client.readPreference = readpref.Primary()
+		}
+	}
+
+	if client.registry == nil {
+		client.registry = bson.DefaultRegistry
+	}
+	return client, nil
+}
+
+func readConcernFromConnString(cs *connstring.ConnString) *readconcern.ReadConcern {
+	if len(cs.ReadConcernLevel) == 0 {
+		return nil
+	}
+
+	rc := &readconcern.ReadConcern{}
+	readconcern.Level(cs.ReadConcernLevel)(rc)
+
+	return rc
+}
+
+func writeConcernFromConnString(cs *connstring.ConnString) *writeconcern.WriteConcern {
+	var wc *writeconcern.WriteConcern
+
+	if len(cs.WString) > 0 {
+		if wc == nil {
+			wc = writeconcern.New()
+		}
+
+		writeconcern.WTagSet(cs.WString)(wc)
+	} else if cs.WNumberSet {
+		if wc == nil {
+			wc = writeconcern.New()
+		}
+
+		writeconcern.W(cs.WNumber)(wc)
+	}
+
+	if cs.JSet {
+		if wc == nil {
+			wc = writeconcern.New()
+		}
+
+		writeconcern.J(cs.J)(wc)
+	}
+
+	if cs.WTimeoutSet {
+		if wc == nil {
+			wc = writeconcern.New()
+		}
+
+		writeconcern.WTimeout(cs.WTimeout)(wc)
+	}
+
+	return wc
+}
+
+func readPreferenceFromConnString(cs *connstring.ConnString) (*readpref.ReadPref, error) {
+	var rp *readpref.ReadPref
+	var err error
+	options := make([]readpref.Option, 0, 1)
+
+	tagSets := tag.NewTagSetsFromMaps(cs.ReadPreferenceTagSets)
+	if len(tagSets) > 0 {
+		options = append(options, readpref.WithTagSets(tagSets...))
+	}
+
+	if cs.MaxStaleness != 0 {
+		options = append(options, readpref.WithMaxStaleness(cs.MaxStaleness))
+	}
+
+	if len(cs.ReadPreference) > 0 {
+		if rp == nil {
+			mode, _ := readpref.ModeFromString(cs.ReadPreference)
+			rp, err = readpref.New(mode, options...)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	return rp, nil
+}
+
+// ValidSession returns an error if the session doesn't belong to the client
+func (c *Client) ValidSession(sess *session.Client) error {
+	if sess != nil && !uuid.Equal(sess.ClientID, c.id) {
+		return ErrWrongClient
+	}
+	return nil
+}
+
+// Database returns a handle for a given database.
+func (c *Client) Database(name string, opts ...*options.DatabaseOptions) *Database {
+	return newDatabase(c, name, opts...)
+}
+
+// ConnectionString returns the connection string of the cluster the client is connected to.
+func (c *Client) ConnectionString() string {
+	return c.connString.Original
+}
+
+// ListDatabases returns a ListDatabasesResult.
+func (c *Client) ListDatabases(ctx context.Context, filter interface{}, opts ...*options.ListDatabasesOptions) (ListDatabasesResult, error) {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := c.ValidSession(sess)
+	if err != nil {
+		return ListDatabasesResult{}, err
+	}
+
+	f, err := transformDocument(c.registry, filter)
+	if err != nil {
+		return ListDatabasesResult{}, err
+	}
+
+	cmd := command.ListDatabases{
+		Filter:  f,
+		Session: sess,
+		Clock:   c.clock,
+	}
+
+	readSelector := description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(readpref.Primary()),
+		description.LatencySelector(c.localThreshold),
+	})
+	res, err := driver.ListDatabases(
+		ctx, cmd,
+		c.topology,
+		readSelector,
+		c.id,
+		c.topology.SessionPool,
+		opts...,
+	)
+	if err != nil {
+		return ListDatabasesResult{}, replaceTopologyErr(err)
+	}
+
+	return (ListDatabasesResult{}).fromResult(res), nil
+}
+
+// ListDatabaseNames returns a slice containing the names of all of the databases on the server.
+func (c *Client) ListDatabaseNames(ctx context.Context, filter interface{}, opts ...*options.ListDatabasesOptions) ([]string, error) {
+	opts = append(opts, options.ListDatabases().SetNameOnly(true))
+
+	res, err := c.ListDatabases(ctx, filter, opts...)
+	if err != nil {
+		return nil, err
+	}
+
+	names := make([]string, 0)
+	for _, spec := range res.Databases {
+		names = append(names, spec.Name)
+	}
+
+	return names, nil
+}
+
+// WithSession allows a user to start a session themselves and manage
+// its lifetime. The only way to provide a session to a CRUD method is
+// to invoke that CRUD method with the mongo.SessionContext within the
+// closure. The mongo.SessionContext can be used as a regular context,
+// so methods like context.WithDeadline and context.WithTimeout are
+// supported.
+//
+// If the context.Context already has a mongo.Session attached, that
+// mongo.Session will be replaced with the one provided.
+//
+// Errors returned from the closure are transparently returned from
+// this function.
+func WithSession(ctx context.Context, sess Session, fn func(SessionContext) error) error {
+	return fn(contextWithSession(ctx, sess))
+}
+
+// UseSession creates a default session, that is only valid for the
+// lifetime of the closure. No cleanup outside of closing the session
+// is done upon exiting the closure. This means that an outstanding
+// transaction will be aborted, even if the closure returns an error.
+//
+// If ctx already contains a mongo.Session, that mongo.Session will be
+// replaced with the newly created mongo.Session.
+//
+// Errors returned from the closure are transparently returned from
+// this method.
+func (c *Client) UseSession(ctx context.Context, fn func(SessionContext) error) error {
+	return c.UseSessionWithOptions(ctx, options.Session(), fn)
+}
+
+// UseSessionWithOptions works like UseSession but allows the caller
+// to specify the options used to create the session.
+func (c *Client) UseSessionWithOptions(ctx context.Context, opts *options.SessionOptions, fn func(SessionContext) error) error {
+	defaultSess, err := c.StartSession(opts)
+	if err != nil {
+		return err
+	}
+
+	defer defaultSess.EndSession(ctx)
+
+	sessCtx := sessionContext{
+		Context: context.WithValue(ctx, sessionKey{}, defaultSess),
+		Session: defaultSess,
+	}
+
+	return fn(sessCtx)
+}
+
+// Watch returns a change stream cursor used to receive information of changes to the client. This method is preferred
+// to running a raw aggregation with a $changeStream stage because it supports resumability in the case of some errors.
+// The client must have read concern majority or no read concern for a change stream to be created successfully.
+func (c *Client) Watch(ctx context.Context, pipeline interface{},
+	opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+
+	return newClientChangeStream(ctx, c, pipeline, opts...)
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/collection.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/collection.go
new file mode 100644
index 0000000..fb16775
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/collection.go
@@ -0,0 +1,1298 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"errors"
+	"strings"
+
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+	"github.com/mongodb/mongo-go-driver/x/bsonx"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/description"
+)
+
+// Collection performs operations on a given collection.
+type Collection struct {
+	client         *Client
+	db             *Database
+	name           string
+	readConcern    *readconcern.ReadConcern
+	writeConcern   *writeconcern.WriteConcern
+	readPreference *readpref.ReadPref
+	readSelector   description.ServerSelector
+	writeSelector  description.ServerSelector
+	registry       *bsoncodec.Registry
+}
+
+func newCollection(db *Database, name string, opts ...*options.CollectionOptions) *Collection {
+	collOpt := options.MergeCollectionOptions(opts...)
+
+	rc := db.readConcern
+	if collOpt.ReadConcern != nil {
+		rc = collOpt.ReadConcern
+	}
+
+	wc := db.writeConcern
+	if collOpt.WriteConcern != nil {
+		wc = collOpt.WriteConcern
+	}
+
+	rp := db.readPreference
+	if collOpt.ReadPreference != nil {
+		rp = collOpt.ReadPreference
+	}
+
+	reg := db.registry
+	if collOpt.Registry != nil {
+		reg = collOpt.Registry
+	}
+
+	readSelector := description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(rp),
+		description.LatencySelector(db.client.localThreshold),
+	})
+
+	writeSelector := description.CompositeSelector([]description.ServerSelector{
+		description.WriteSelector(),
+		description.LatencySelector(db.client.localThreshold),
+	})
+
+	coll := &Collection{
+		client:         db.client,
+		db:             db,
+		name:           name,
+		readPreference: rp,
+		readConcern:    rc,
+		writeConcern:   wc,
+		readSelector:   readSelector,
+		writeSelector:  writeSelector,
+		registry:       reg,
+	}
+
+	return coll
+}
+
+func (coll *Collection) copy() *Collection {
+	return &Collection{
+		client:         coll.client,
+		db:             coll.db,
+		name:           coll.name,
+		readConcern:    coll.readConcern,
+		writeConcern:   coll.writeConcern,
+		readPreference: coll.readPreference,
+		readSelector:   coll.readSelector,
+		writeSelector:  coll.writeSelector,
+		registry:       coll.registry,
+	}
+}
+
+// Clone creates a copy of this collection with updated options, if any are given.
+func (coll *Collection) Clone(opts ...*options.CollectionOptions) (*Collection, error) {
+	copyColl := coll.copy()
+	optsColl := options.MergeCollectionOptions(opts...)
+
+	if optsColl.ReadConcern != nil {
+		copyColl.readConcern = optsColl.ReadConcern
+	}
+
+	if optsColl.WriteConcern != nil {
+		copyColl.writeConcern = optsColl.WriteConcern
+	}
+
+	if optsColl.ReadPreference != nil {
+		copyColl.readPreference = optsColl.ReadPreference
+	}
+
+	if optsColl.Registry != nil {
+		copyColl.registry = optsColl.Registry
+	}
+
+	copyColl.readSelector = description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(copyColl.readPreference),
+		description.LatencySelector(copyColl.client.localThreshold),
+	})
+
+	return copyColl, nil
+}
+
+// Name provides access to the name of the collection.
+func (coll *Collection) Name() string {
+	return coll.name
+}
+
+// namespace returns the namespace of the collection.
+func (coll *Collection) namespace() command.Namespace {
+	return command.NewNamespace(coll.db.name, coll.name)
+}
+
+// Database provides access to the database that contains the collection.
+func (coll *Collection) Database() *Database {
+	return coll.db
+}
+
+// BulkWrite performs a bulk write operation.
+//
+// See https://docs.mongodb.com/manual/core/bulk-write-operations/.
+func (coll *Collection) BulkWrite(ctx context.Context, models []WriteModel,
+	opts ...*options.BulkWriteOptions) (*BulkWriteResult, error) {
+
+	if len(models) == 0 {
+		return nil, ErrEmptySlice
+	}
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	dispatchModels := make([]driver.WriteModel, len(models))
+	for i, model := range models {
+		if model == nil {
+			return nil, ErrNilDocument
+		}
+		dispatchModels[i] = model.convertModel()
+	}
+
+	res, err := driver.BulkWrite(
+		ctx,
+		coll.namespace(),
+		dispatchModels,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		sess,
+		coll.writeConcern,
+		coll.client.clock,
+		coll.registry,
+		opts...,
+	)
+
+	if err != nil {
+		if conv, ok := err.(driver.BulkWriteException); ok {
+			return &BulkWriteResult{}, BulkWriteException{
+				WriteConcernError: convertWriteConcernError(conv.WriteConcernError),
+				WriteErrors:       convertBulkWriteErrors(conv.WriteErrors),
+			}
+		}
+
+		return &BulkWriteResult{}, replaceTopologyErr(err)
+	}
+
+	return &BulkWriteResult{
+		InsertedCount: res.InsertedCount,
+		MatchedCount:  res.MatchedCount,
+		ModifiedCount: res.ModifiedCount,
+		DeletedCount:  res.DeletedCount,
+		UpsertedCount: res.UpsertedCount,
+		UpsertedIDs:   res.UpsertedIDs,
+	}, nil
+}
+
+// InsertOne inserts a single document into the collection.
+func (coll *Collection) InsertOne(ctx context.Context, document interface{},
+	opts ...*options.InsertOneOptions) (*InsertOneResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	doc, insertedID, err := transformAndEnsureID(coll.registry, document)
+	if err != nil {
+		return nil, err
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+	oldns := coll.namespace()
+	cmd := command.Insert{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Docs:         []bsonx.Doc{doc},
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	// convert to InsertManyOptions so these can be argued to dispatch.Insert
+	insertOpts := make([]*options.InsertManyOptions, len(opts))
+	for i, opt := range opts {
+		insertOpts[i] = options.InsertMany()
+		insertOpts[i].BypassDocumentValidation = opt.BypassDocumentValidation
+	}
+
+	res, err := driver.Insert(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		insertOpts...,
+	)
+
+	rr, err := processWriteError(res.WriteConcernError, res.WriteErrors, err)
+	if rr&rrOne == 0 {
+		return nil, err
+	}
+
+	return &InsertOneResult{InsertedID: insertedID}, err
+}
+
+// InsertMany inserts the provided documents.
+func (coll *Collection) InsertMany(ctx context.Context, documents []interface{},
+	opts ...*options.InsertManyOptions) (*InsertManyResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	if len(documents) == 0 {
+		return nil, ErrEmptySlice
+	}
+
+	result := make([]interface{}, len(documents))
+	docs := make([]bsonx.Doc, len(documents))
+
+	for i, doc := range documents {
+		if doc == nil {
+			return nil, ErrNilDocument
+		}
+		bdoc, insertedID, err := transformAndEnsureID(coll.registry, doc)
+		if err != nil {
+			return nil, err
+		}
+
+		docs[i] = bdoc
+		result[i] = insertedID
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Insert{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Docs:         docs,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	res, err := driver.Insert(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		opts...,
+	)
+
+	switch err {
+	case nil:
+	case command.ErrUnacknowledgedWrite:
+		return &InsertManyResult{InsertedIDs: result}, ErrUnacknowledgedWrite
+	default:
+		return nil, replaceTopologyErr(err)
+	}
+	if len(res.WriteErrors) > 0 || res.WriteConcernError != nil {
+		bwErrors := make([]BulkWriteError, 0, len(res.WriteErrors))
+		for _, we := range res.WriteErrors {
+			bwErrors = append(bwErrors, BulkWriteError{
+				WriteError{
+					Index:   we.Index,
+					Code:    we.Code,
+					Message: we.ErrMsg,
+				},
+				nil,
+			})
+		}
+
+		err = BulkWriteException{
+			WriteErrors:       bwErrors,
+			WriteConcernError: convertWriteConcernError(res.WriteConcernError),
+		}
+	}
+
+	return &InsertManyResult{InsertedIDs: result}, err
+}
+
+// DeleteOne deletes a single document from the collection.
+func (coll *Collection) DeleteOne(ctx context.Context, filter interface{},
+	opts ...*options.DeleteOptions) (*DeleteResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+	deleteDocs := []bsonx.Doc{
+		{
+			{"q", bsonx.Document(f)},
+			{"limit", bsonx.Int32(1)},
+		},
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Delete{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Deletes:      deleteDocs,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	res, err := driver.Delete(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		opts...,
+	)
+
+	rr, err := processWriteError(res.WriteConcernError, res.WriteErrors, err)
+	if rr&rrOne == 0 {
+		return nil, err
+	}
+	return &DeleteResult{DeletedCount: int64(res.N)}, err
+}
+
+// DeleteMany deletes multiple documents from the collection.
+func (coll *Collection) DeleteMany(ctx context.Context, filter interface{},
+	opts ...*options.DeleteOptions) (*DeleteResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+	deleteDocs := []bsonx.Doc{{{"q", bsonx.Document(f)}, {"limit", bsonx.Int32(0)}}}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Delete{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Deletes:      deleteDocs,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	res, err := driver.Delete(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		false,
+		opts...,
+	)
+
+	rr, err := processWriteError(res.WriteConcernError, res.WriteErrors, err)
+	if rr&rrMany == 0 {
+		return nil, err
+	}
+	return &DeleteResult{DeletedCount: int64(res.N)}, err
+}
+
+func (coll *Collection) updateOrReplaceOne(ctx context.Context, filter,
+	update bsonx.Doc, sess *session.Client, opts ...*options.UpdateOptions) (*UpdateResult, error) {
+
+	// TODO: should session be taken from ctx or left as argument?
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	updateDocs := []bsonx.Doc{
+		{
+			{"q", bsonx.Document(filter)},
+			{"u", bsonx.Document(update)},
+			{"multi", bsonx.Boolean(false)},
+		},
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Update{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Docs:         updateDocs,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	r, err := driver.Update(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		opts...,
+	)
+	if err != nil && err != command.ErrUnacknowledgedWrite {
+		return nil, replaceTopologyErr(err)
+	}
+
+	res := &UpdateResult{
+		MatchedCount:  r.MatchedCount,
+		ModifiedCount: r.ModifiedCount,
+		UpsertedCount: int64(len(r.Upserted)),
+	}
+	if len(r.Upserted) > 0 {
+		res.UpsertedID = r.Upserted[0].ID
+		res.MatchedCount--
+	}
+
+	rr, err := processWriteError(r.WriteConcernError, r.WriteErrors, err)
+	if rr&rrOne == 0 {
+		return nil, err
+	}
+	return res, err
+}
+
+// UpdateOne updates a single document in the collection.
+func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{},
+	opts ...*options.UpdateOptions) (*UpdateResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	u, err := transformDocument(coll.registry, update)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := ensureDollarKey(u); err != nil {
+		return nil, err
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	return coll.updateOrReplaceOne(ctx, f, u, sess, opts...)
+}
+
+// UpdateMany updates multiple documents in the collection.
+func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, update interface{},
+	opts ...*options.UpdateOptions) (*UpdateResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	u, err := transformDocument(coll.registry, update)
+	if err != nil {
+		return nil, err
+	}
+
+	if err = ensureDollarKey(u); err != nil {
+		return nil, err
+	}
+
+	updateDocs := []bsonx.Doc{
+		{
+			{"q", bsonx.Document(f)},
+			{"u", bsonx.Document(u)},
+			{"multi", bsonx.Boolean(true)},
+		},
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Update{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Docs:         updateDocs,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	r, err := driver.Update(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		false,
+		opts...,
+	)
+	if err != nil && err != command.ErrUnacknowledgedWrite {
+		return nil, replaceTopologyErr(err)
+	}
+	res := &UpdateResult{
+		MatchedCount:  r.MatchedCount,
+		ModifiedCount: r.ModifiedCount,
+		UpsertedCount: int64(len(r.Upserted)),
+	}
+	// TODO(skriptble): Is this correct? Do we only return the first upserted ID for an UpdateMany?
+	if len(r.Upserted) > 0 {
+		res.UpsertedID = r.Upserted[0].ID
+		res.MatchedCount--
+	}
+
+	rr, err := processWriteError(r.WriteConcernError, r.WriteErrors, err)
+	if rr&rrMany == 0 {
+		return nil, err
+	}
+	return res, err
+}
+
+// ReplaceOne replaces a single document in the collection.
+func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{},
+	replacement interface{}, opts ...*options.ReplaceOptions) (*UpdateResult, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	r, err := transformDocument(coll.registry, replacement)
+	if err != nil {
+		return nil, err
+	}
+
+	if len(r) > 0 && strings.HasPrefix(r[0].Key, "$") {
+		return nil, errors.New("replacement document cannot contains keys beginning with '$")
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	updateOptions := make([]*options.UpdateOptions, 0, len(opts))
+	for _, opt := range opts {
+		uOpts := options.Update()
+		uOpts.BypassDocumentValidation = opt.BypassDocumentValidation
+		uOpts.Collation = opt.Collation
+		uOpts.Upsert = opt.Upsert
+		updateOptions = append(updateOptions, uOpts)
+	}
+
+	return coll.updateOrReplaceOne(ctx, f, r, sess, updateOptions...)
+}
+
+// Aggregate runs an aggregation framework pipeline.
+//
+// See https://docs.mongodb.com/manual/aggregation/.
+func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{},
+	opts ...*options.AggregateOptions) (*Cursor, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	pipelineArr, err := transformAggregatePipeline(coll.registry, pipeline)
+	if err != nil {
+		return nil, err
+	}
+
+	aggOpts := options.MergeAggregateOptions(opts...)
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Aggregate{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Pipeline:     pipelineArr,
+		ReadPref:     coll.readPreference,
+		WriteConcern: wc,
+		ReadConcern:  rc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	batchCursor, err := driver.Aggregate(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.registry,
+		aggOpts,
+	)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+
+	cursor, err := newCursor(batchCursor, coll.registry)
+	return cursor, replaceTopologyErr(err)
+}
+
+// Count gets the number of documents matching the filter.
+func (coll *Collection) Count(ctx context.Context, filter interface{},
+	opts ...*options.CountOptions) (int64, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return 0, err
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return 0, err
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Count{
+		NS:          command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Query:       f,
+		ReadPref:    coll.readPreference,
+		ReadConcern: rc,
+		Session:     sess,
+		Clock:       coll.client.clock,
+	}
+
+	count, err := driver.Count(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.registry,
+		opts...,
+	)
+
+	return count, replaceTopologyErr(err)
+}
+
+// CountDocuments gets the number of documents matching the filter.
+func (coll *Collection) CountDocuments(ctx context.Context, filter interface{},
+	opts ...*options.CountOptions) (int64, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	countOpts := options.MergeCountOptions(opts...)
+
+	pipelineArr, err := countDocumentsAggregatePipeline(coll.registry, filter, countOpts)
+	if err != nil {
+		return 0, err
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return 0, err
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.CountDocuments{
+		NS:          command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Pipeline:    pipelineArr,
+		ReadPref:    coll.readPreference,
+		ReadConcern: rc,
+		Session:     sess,
+		Clock:       coll.client.clock,
+	}
+
+	count, err := driver.CountDocuments(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.registry,
+		countOpts,
+	)
+
+	return count, replaceTopologyErr(err)
+}
+
+// EstimatedDocumentCount gets an estimate of the count of documents in a collection using collection metadata.
+func (coll *Collection) EstimatedDocumentCount(ctx context.Context,
+	opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := coll.client.ValidSession(sess)
+	if err != nil {
+		return 0, err
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Count{
+		NS:          command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Query:       bsonx.Doc{},
+		ReadPref:    coll.readPreference,
+		ReadConcern: rc,
+		Session:     sess,
+		Clock:       coll.client.clock,
+	}
+
+	countOpts := options.Count()
+	if len(opts) >= 1 {
+		countOpts = countOpts.SetMaxTime(*opts[len(opts)-1].MaxTime)
+	}
+
+	count, err := driver.Count(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.registry,
+		countOpts,
+	)
+
+	return count, replaceTopologyErr(err)
+}
+
+// Distinct finds the distinct values for a specified field across a single
+// collection.
+func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{},
+	opts ...*options.DistinctOptions) ([]interface{}, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Distinct{
+		NS:          command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Field:       fieldName,
+		Query:       f,
+		ReadPref:    coll.readPreference,
+		ReadConcern: rc,
+		Session:     sess,
+		Clock:       coll.client.clock,
+	}
+
+	res, err := driver.Distinct(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		opts...,
+	)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+
+	return res.Values, nil
+}
+
+// Find finds the documents matching a model.
+func (coll *Collection) Find(ctx context.Context, filter interface{},
+	opts ...*options.FindOptions) (*Cursor, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Find{
+		NS:          command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Filter:      f,
+		ReadPref:    coll.readPreference,
+		ReadConcern: rc,
+		Session:     sess,
+		Clock:       coll.client.clock,
+	}
+
+	batchCursor, err := driver.Find(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.registry,
+		opts...,
+	)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+
+	cursor, err := newCursor(batchCursor, coll.registry)
+	return cursor, replaceTopologyErr(err)
+}
+
+// FindOne returns up to one document that matches the model.
+func (coll *Collection) FindOne(ctx context.Context, filter interface{},
+	opts ...*options.FindOneOptions) *SingleResult {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	rc := coll.readConcern
+	if sess != nil && (sess.TransactionInProgress()) {
+		rc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.Find{
+		NS:          command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Filter:      f,
+		ReadPref:    coll.readPreference,
+		ReadConcern: rc,
+		Session:     sess,
+		Clock:       coll.client.clock,
+	}
+
+	findOpts := make([]*options.FindOptions, len(opts))
+	for i, opt := range opts {
+		findOpts[i] = &options.FindOptions{
+			AllowPartialResults: opt.AllowPartialResults,
+			BatchSize:           opt.BatchSize,
+			Collation:           opt.Collation,
+			Comment:             opt.Comment,
+			CursorType:          opt.CursorType,
+			Hint:                opt.Hint,
+			Max:                 opt.Max,
+			MaxAwaitTime:        opt.MaxAwaitTime,
+			Min:                 opt.Min,
+			NoCursorTimeout:     opt.NoCursorTimeout,
+			OplogReplay:         opt.OplogReplay,
+			Projection:          opt.Projection,
+			ReturnKey:           opt.ReturnKey,
+			ShowRecordID:        opt.ShowRecordID,
+			Skip:                opt.Skip,
+			Snapshot:            opt.Snapshot,
+			Sort:                opt.Sort,
+		}
+	}
+
+	batchCursor, err := driver.Find(
+		ctx, cmd,
+		coll.client.topology,
+		coll.readSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.registry,
+		findOpts...,
+	)
+	if err != nil {
+		return &SingleResult{err: replaceTopologyErr(err)}
+	}
+
+	cursor, err := newCursor(batchCursor, coll.registry)
+	return &SingleResult{cur: cursor, reg: coll.registry, err: replaceTopologyErr(err)}
+}
+
+// FindOneAndDelete find a single document and deletes it, returning the
+// original in result.
+func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{},
+	opts ...*options.FindOneAndDeleteOptions) *SingleResult {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	oldns := coll.namespace()
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	cmd := command.FindOneAndDelete{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Query:        f,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	res, err := driver.FindOneAndDelete(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		coll.registry,
+		opts...,
+	)
+	if err != nil {
+		return &SingleResult{err: replaceTopologyErr(err)}
+	}
+
+	return &SingleResult{rdr: res.Value, reg: coll.registry}
+}
+
+// FindOneAndReplace finds a single document and replaces it, returning either
+// the original or the replaced document.
+func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{},
+	replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *SingleResult {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	r, err := transformDocument(coll.registry, replacement)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	if len(r) > 0 && strings.HasPrefix(r[0].Key, "$") {
+		return &SingleResult{err: errors.New("replacement document cannot contains keys beginning with '$")}
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.FindOneAndReplace{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Query:        f,
+		Replacement:  r,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	res, err := driver.FindOneAndReplace(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		coll.registry,
+		opts...,
+	)
+	if err != nil {
+		return &SingleResult{err: replaceTopologyErr(err)}
+	}
+
+	return &SingleResult{rdr: res.Value, reg: coll.registry}
+}
+
+// FindOneAndUpdate finds a single document and updates it, returning either
+// the original or the updated.
+func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{},
+	update interface{}, opts ...*options.FindOneAndUpdateOptions) *SingleResult {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	f, err := transformDocument(coll.registry, filter)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	u, err := transformDocument(coll.registry, update)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	err = ensureDollarKey(u)
+	if err != nil {
+		return &SingleResult{
+			err: err,
+		}
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err = coll.client.ValidSession(sess)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	oldns := coll.namespace()
+	cmd := command.FindOneAndUpdate{
+		NS:           command.Namespace{DB: oldns.DB, Collection: oldns.Collection},
+		Query:        f,
+		Update:       u,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+
+	res, err := driver.FindOneAndUpdate(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+		coll.client.retryWrites,
+		coll.registry,
+		opts...,
+	)
+	if err != nil {
+		return &SingleResult{err: replaceTopologyErr(err)}
+	}
+
+	return &SingleResult{rdr: res.Value, reg: coll.registry}
+}
+
+// Watch returns a change stream cursor used to receive notifications of changes to the collection.
+//
+// This method is preferred to running a raw aggregation with a $changeStream stage because it
+// supports resumability in the case of some errors. The collection must have read concern majority or no read concern
+// for a change stream to be created successfully.
+func (coll *Collection) Watch(ctx context.Context, pipeline interface{},
+	opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+	return newChangeStream(ctx, coll, pipeline, opts...)
+}
+
+// Indexes returns the index view for this collection.
+func (coll *Collection) Indexes() IndexView {
+	return IndexView{coll: coll}
+}
+
+// Drop drops this collection from database.
+func (coll *Collection) Drop(ctx context.Context) error {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := coll.client.ValidSession(sess)
+	if err != nil {
+		return err
+	}
+
+	wc := coll.writeConcern
+	if sess != nil && sess.TransactionRunning() {
+		wc = nil
+	}
+
+	cmd := command.DropCollection{
+		DB:           coll.db.name,
+		Collection:   coll.name,
+		WriteConcern: wc,
+		Session:      sess,
+		Clock:        coll.client.clock,
+	}
+	_, err = driver.DropCollection(
+		ctx, cmd,
+		coll.client.topology,
+		coll.writeSelector,
+		coll.client.id,
+		coll.client.topology.SessionPool,
+	)
+	if err != nil && !command.IsNotFound(err) {
+		return replaceTopologyErr(err)
+	}
+	return nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/cursor.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/cursor.go
new file mode 100644
index 0000000..a9dc13d
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/cursor.go
@@ -0,0 +1,137 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"errors"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+)
+
+// Cursor is used to iterate a stream of documents. Each document is decoded into the result
+// according to the rules of the bson package.
+//
+// A typical usage of the Cursor type would be:
+//
+//		var cur *Cursor
+//		ctx := context.Background()
+//		defer cur.Close(ctx)
+//
+// 		for cur.Next(ctx) {
+//			elem := &bson.D{}
+//			if err := cur.Decode(elem); err != nil {
+// 				log.Fatal(err)
+// 			}
+//
+// 			// do something with elem....
+//		}
+//
+// 		if err := cur.Err(); err != nil {
+//			log.Fatal(err)
+//		}
+//
+type Cursor struct {
+	// Current is the BSON bytes of the current document. This property is only valid until the next
+	// call to Next or Close. If continued access is required to the bson.Raw, you must make a copy
+	// of it.
+	Current bson.Raw
+
+	bc       batchCursor
+	pos      int
+	batch    []byte
+	registry *bsoncodec.Registry
+
+	err error
+}
+
+func newCursor(bc batchCursor, registry *bsoncodec.Registry) (*Cursor, error) {
+	if registry == nil {
+		registry = bson.DefaultRegistry
+	}
+	if bc == nil {
+		return nil, errors.New("batch cursor must not be nil")
+	}
+	return &Cursor{bc: bc, pos: 0, batch: make([]byte, 0, 256), registry: registry}, nil
+}
+
+func newEmptyCursor() *Cursor {
+	return &Cursor{bc: driver.NewEmptyBatchCursor()}
+}
+
+// ID returns the ID of this cursor.
+func (c *Cursor) ID() int64 { return c.bc.ID() }
+
+func (c *Cursor) advanceCurrentDocument() bool {
+	if len(c.batch[c.pos:]) < 4 {
+		c.err = errors.New("could not read next document: insufficient bytes")
+		return false
+	}
+	length := (int(c.batch[c.pos]) | int(c.batch[c.pos+1])<<8 | int(c.batch[c.pos+2])<<16 | int(c.batch[c.pos+3])<<24)
+	if len(c.batch[c.pos:]) < length {
+		c.err = errors.New("could not read next document: insufficient bytes")
+		return false
+	}
+	if len(c.Current) > 4 {
+		c.Current[0], c.Current[1], c.Current[2], c.Current[3] = 0x00, 0x00, 0x00, 0x00 // Invalidate the current document
+	}
+	c.Current = c.batch[c.pos : c.pos+length]
+	c.pos += length
+	return true
+}
+
+// Next gets the next result from this cursor. Returns true if there were no errors and the next
+// result is available for decoding.
+func (c *Cursor) Next(ctx context.Context) bool {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+	if c.pos < len(c.batch) {
+		return c.advanceCurrentDocument()
+	}
+
+	// clear the batch
+	c.batch = c.batch[:0]
+	c.pos = 0
+	c.Current = c.Current[:0]
+
+	// call the Next method in a loop until at least one document is returned in the next batch or
+	// the context times out.
+	for len(c.batch) == 0 {
+		// If we don't have a next batch
+		if !c.bc.Next(ctx) {
+			// Do we have an error? If so we return false.
+			c.err = c.bc.Err()
+			if c.err != nil {
+				return false
+			}
+			// Is the cursor ID zero?
+			if c.bc.ID() == 0 {
+				return false
+			}
+			// empty batch, but cursor is still valid, so continue.
+			continue
+		}
+
+		c.batch = c.bc.Batch(c.batch[:0])
+	}
+
+	return c.advanceCurrentDocument()
+}
+
+// Decode will decode the current document into val.
+func (c *Cursor) Decode(val interface{}) error {
+	return bson.UnmarshalWithRegistry(c.registry, c.Current, val)
+}
+
+// Err returns the current error.
+func (c *Cursor) Err() error { return c.err }
+
+// Close closes this cursor.
+func (c *Cursor) Close(ctx context.Context) error { return c.bc.Close(ctx) }
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/database.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/database.go
new file mode 100644
index 0000000..9575e06
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/database.go
@@ -0,0 +1,282 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/description"
+)
+
+// Database performs operations on a given database.
+type Database struct {
+	client         *Client
+	name           string
+	readConcern    *readconcern.ReadConcern
+	writeConcern   *writeconcern.WriteConcern
+	readPreference *readpref.ReadPref
+	readSelector   description.ServerSelector
+	writeSelector  description.ServerSelector
+	registry       *bsoncodec.Registry
+}
+
+func newDatabase(client *Client, name string, opts ...*options.DatabaseOptions) *Database {
+	dbOpt := options.MergeDatabaseOptions(opts...)
+
+	rc := client.readConcern
+	if dbOpt.ReadConcern != nil {
+		rc = dbOpt.ReadConcern
+	}
+
+	rp := client.readPreference
+	if dbOpt.ReadPreference != nil {
+		rp = dbOpt.ReadPreference
+	}
+
+	wc := client.writeConcern
+	if dbOpt.WriteConcern != nil {
+		wc = dbOpt.WriteConcern
+	}
+
+	db := &Database{
+		client:         client,
+		name:           name,
+		readPreference: rp,
+		readConcern:    rc,
+		writeConcern:   wc,
+		registry:       client.registry,
+	}
+
+	db.readSelector = description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(db.readPreference),
+		description.LatencySelector(db.client.localThreshold),
+	})
+
+	db.writeSelector = description.CompositeSelector([]description.ServerSelector{
+		description.WriteSelector(),
+		description.LatencySelector(db.client.localThreshold),
+	})
+
+	return db
+}
+
+// Client returns the Client the database was created from.
+func (db *Database) Client() *Client {
+	return db.client
+}
+
+// Name returns the name of the database.
+func (db *Database) Name() string {
+	return db.name
+}
+
+// Collection gets a handle for a given collection in the database.
+func (db *Database) Collection(name string, opts ...*options.CollectionOptions) *Collection {
+	return newCollection(db, name, opts...)
+}
+
+func (db *Database) processRunCommand(ctx context.Context, cmd interface{}, opts ...*options.RunCmdOptions) (command.Read,
+	description.ServerSelector, error) {
+
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+	runCmd := options.MergeRunCmdOptions(opts...)
+
+	if err := db.client.ValidSession(sess); err != nil {
+		return command.Read{}, nil, err
+	}
+
+	rp := runCmd.ReadPreference
+	if rp == nil {
+		if sess != nil && sess.TransactionRunning() {
+			rp = sess.CurrentRp // override with transaction read pref if specified
+		}
+		if rp == nil {
+			rp = readpref.Primary() // set to primary if nothing specified in options
+		}
+	}
+
+	runCmdDoc, err := transformDocument(db.registry, cmd)
+	if err != nil {
+		return command.Read{}, nil, err
+	}
+
+	readSelect := description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(rp),
+		description.LatencySelector(db.client.localThreshold),
+	})
+
+	return command.Read{
+		DB:       db.Name(),
+		Command:  runCmdDoc,
+		ReadPref: rp,
+		Session:  sess,
+		Clock:    db.client.clock,
+	}, readSelect, nil
+}
+
+// RunCommand runs a command on the database. A user can supply a custom
+// context to this method, or nil to default to context.Background().
+func (db *Database) RunCommand(ctx context.Context, runCommand interface{}, opts ...*options.RunCmdOptions) *SingleResult {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	readCmd, readSelect, err := db.processRunCommand(ctx, runCommand, opts...)
+	if err != nil {
+		return &SingleResult{err: err}
+	}
+
+	doc, err := driver.Read(ctx,
+		readCmd,
+		db.client.topology,
+		readSelect,
+		db.client.id,
+		db.client.topology.SessionPool,
+	)
+
+	return &SingleResult{err: replaceTopologyErr(err), rdr: doc, reg: db.registry}
+}
+
+// RunCommandCursor runs a command on the database and returns a cursor over the resulting reader. A user can supply
+// a custom context to this method, or nil to default to context.Background().
+func (db *Database) RunCommandCursor(ctx context.Context, runCommand interface{}, opts ...*options.RunCmdOptions) (*Cursor, error) {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	readCmd, readSelect, err := db.processRunCommand(ctx, runCommand, opts...)
+	if err != nil {
+		return nil, err
+	}
+
+	batchCursor, err := driver.ReadCursor(
+		ctx,
+		readCmd,
+		db.client.topology,
+		readSelect,
+		db.client.id,
+		db.client.topology.SessionPool,
+	)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+
+	cursor, err := newCursor(batchCursor, db.registry)
+	return cursor, replaceTopologyErr(err)
+}
+
+// Drop drops this database from mongodb.
+func (db *Database) Drop(ctx context.Context) error {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := db.client.ValidSession(sess)
+	if err != nil {
+		return err
+	}
+
+	cmd := command.DropDatabase{
+		DB:      db.name,
+		Session: sess,
+		Clock:   db.client.clock,
+	}
+	_, err = driver.DropDatabase(
+		ctx, cmd,
+		db.client.topology,
+		db.writeSelector,
+		db.client.id,
+		db.client.topology.SessionPool,
+	)
+	if err != nil && !command.IsNotFound(err) {
+		return replaceTopologyErr(err)
+	}
+	return nil
+}
+
+// ListCollections list collections from mongodb database.
+func (db *Database) ListCollections(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) (*Cursor, error) {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := db.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	filterDoc, err := transformDocument(db.registry, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	cmd := command.ListCollections{
+		DB:       db.name,
+		Filter:   filterDoc,
+		ReadPref: readpref.Primary(), // list collections must be run on a primary by default
+		Session:  sess,
+		Clock:    db.client.clock,
+	}
+
+	readSelector := description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(readpref.Primary()),
+		description.LatencySelector(db.client.localThreshold),
+	})
+	batchCursor, err := driver.ListCollections(
+		ctx, cmd,
+		db.client.topology,
+		readSelector,
+		db.client.id,
+		db.client.topology.SessionPool,
+		opts...,
+	)
+	if err != nil {
+		return nil, replaceTopologyErr(err)
+	}
+
+	cursor, err := newCursor(batchCursor, db.registry)
+	return cursor, replaceTopologyErr(err)
+}
+
+// ReadConcern returns the read concern of this database.
+func (db *Database) ReadConcern() *readconcern.ReadConcern {
+	return db.readConcern
+}
+
+// ReadPreference returns the read preference of this database.
+func (db *Database) ReadPreference() *readpref.ReadPref {
+	return db.readPreference
+}
+
+// WriteConcern returns the write concern of this database.
+func (db *Database) WriteConcern() *writeconcern.WriteConcern {
+	return db.writeConcern
+}
+
+// Watch returns a change stream cursor used to receive information of changes to the database. This method is preferred
+// to running a raw aggregation with a $changeStream stage because it supports resumability in the case of some errors.
+// The database must have read concern majority or no read concern for a change stream to be created successfully.
+func (db *Database) Watch(ctx context.Context, pipeline interface{},
+	opts ...*options.ChangeStreamOptions) (*ChangeStream, error) {
+
+	return newDbChangeStream(ctx, db, pipeline, opts...)
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/doc.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/doc.go
new file mode 100644
index 0000000..4f7f819
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/doc.go
@@ -0,0 +1,60 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+// NOTE: This documentation should be kept in line with the Example* test functions.
+
+// Package mongo provides a MongoDB Driver API for Go.
+//
+// Basic usage of the driver starts with creating a Client from a connection
+// string. To do so, call the NewClient and Connect functions:
+//
+// 		client, err := NewClient("mongodb://foo:bar@localhost:27017")
+// 		if err != nil { return err }
+// 		ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
+// 		defer cancel()
+// 		err = client.Connect(ctx)
+// 		if err != nil { return err }
+//
+// This will create a new client and start monitoring the MongoDB server on localhost.
+// The Database and Collection types can be used to access the database:
+//
+//    collection := client.Database("baz").Collection("qux")
+//
+// A Collection can be used to query the database or insert documents:
+//
+//    res, err := collection.InsertOne(context.Background(), bson.M{"hello": "world"})
+//    if err != nil { return err }
+//    id := res.InsertedID
+//
+// Several methods return a cursor, which can be used like this:
+//
+//    cur, err := collection.Find(context.Background(), bson.D{})
+//    if err != nil { log.Fatal(err) }
+//    defer cur.Close(context.Background())
+//    for cur.Next(context.Background()) {
+//       raw, err := cur.DecodeBytes()
+//       if err != nil { log.Fatal(err) }
+//       // do something with elem....
+//    }
+//    if err := cur.Err(); err != nil {
+//    		return err
+//    }
+//
+// Methods that only return a single document will return a *SingleResult, which works
+// like a *sql.Row:
+//
+// 	  result := struct{
+// 	  	Foo string
+// 	  	Bar int32
+// 	  }{}
+//    filter := bson.D{{"hello", "world"}}
+//    err := collection.FindOne(context.Background(), filter).Decode(&result)
+//    if err != nil { return err }
+//    // do something with result...
+//
+// Additional examples can be found under the examples directory in the driver's repository and
+// on the MongoDB website.
+package mongo
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/errors.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/errors.go
new file mode 100644
index 0000000..3505bcc
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/errors.go
@@ -0,0 +1,186 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/result"
+)
+
+// ErrUnacknowledgedWrite is returned from functions that have an unacknowledged
+// write concern.
+var ErrUnacknowledgedWrite = errors.New("unacknowledged write")
+
+// ErrClientDisconnected is returned when a user attempts to call a method on a
+// disconnected client
+var ErrClientDisconnected = errors.New("client is disconnected")
+
+// ErrNilDocument is returned when a user attempts to pass a nil document or filter
+// to a function where the field is required.
+var ErrNilDocument = errors.New("document is nil")
+
+// ErrEmptySlice is returned when a user attempts to pass an empty slice as input
+// to a function wehere the field is required.
+var ErrEmptySlice = errors.New("must provide at least one element in input slice")
+
+func replaceTopologyErr(err error) error {
+	if err == topology.ErrTopologyClosed {
+		return ErrClientDisconnected
+	}
+	return err
+}
+
+// WriteError is a non-write concern failure that occurred as a result of a write
+// operation.
+type WriteError struct {
+	Index   int
+	Code    int
+	Message string
+}
+
+func (we WriteError) Error() string { return we.Message }
+
+// WriteErrors is a group of non-write concern failures that occurred as a result
+// of a write operation.
+type WriteErrors []WriteError
+
+func (we WriteErrors) Error() string {
+	var buf bytes.Buffer
+	fmt.Fprint(&buf, "write errors: [")
+	for idx, err := range we {
+		if idx != 0 {
+			fmt.Fprintf(&buf, ", ")
+		}
+		fmt.Fprintf(&buf, "{%s}", err)
+	}
+	fmt.Fprint(&buf, "]")
+	return buf.String()
+}
+
+func writeErrorsFromResult(rwes []result.WriteError) WriteErrors {
+	wes := make(WriteErrors, 0, len(rwes))
+	for _, err := range rwes {
+		wes = append(wes, WriteError{Index: err.Index, Code: err.Code, Message: err.ErrMsg})
+	}
+	return wes
+}
+
+// WriteConcernError is a write concern failure that occurred as a result of a
+// write operation.
+type WriteConcernError struct {
+	Code    int
+	Message string
+	Details bson.Raw
+}
+
+func (wce WriteConcernError) Error() string { return wce.Message }
+
+// WriteException is an error for a non-bulk write operation.
+type WriteException struct {
+	WriteConcernError *WriteConcernError
+	WriteErrors       WriteErrors
+}
+
+func (mwe WriteException) Error() string {
+	var buf bytes.Buffer
+	fmt.Fprint(&buf, "multiple write errors: [")
+	fmt.Fprintf(&buf, "{%s}, ", mwe.WriteErrors)
+	fmt.Fprintf(&buf, "{%s}]", mwe.WriteConcernError)
+	return buf.String()
+}
+
+func convertBulkWriteErrors(errors []driver.BulkWriteError) []BulkWriteError {
+	bwErrors := make([]BulkWriteError, 0, len(errors))
+	for _, err := range errors {
+		bwErrors = append(bwErrors, BulkWriteError{
+			WriteError{
+				Index:   err.Index,
+				Code:    err.Code,
+				Message: err.ErrMsg,
+			},
+			dispatchToMongoModel(err.Model),
+		})
+	}
+
+	return bwErrors
+}
+
+func convertWriteConcernError(wce *result.WriteConcernError) *WriteConcernError {
+	if wce == nil {
+		return nil
+	}
+
+	return &WriteConcernError{Code: wce.Code, Message: wce.ErrMsg, Details: wce.ErrInfo}
+}
+
+// BulkWriteError is an error for one operation in a bulk write.
+type BulkWriteError struct {
+	WriteError
+	Request WriteModel
+}
+
+func (bwe BulkWriteError) Error() string {
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "{%s}", bwe.WriteError)
+	return buf.String()
+}
+
+// BulkWriteException is an error for a bulk write operation.
+type BulkWriteException struct {
+	WriteConcernError *WriteConcernError
+	WriteErrors       []BulkWriteError
+}
+
+func (bwe BulkWriteException) Error() string {
+	var buf bytes.Buffer
+	fmt.Fprint(&buf, "bulk write error: [")
+	fmt.Fprintf(&buf, "{%s}, ", bwe.WriteErrors)
+	fmt.Fprintf(&buf, "{%s}]", bwe.WriteConcernError)
+	return buf.String()
+}
+
+// returnResult is used to determine if a function calling processWriteError should return
+// the result or return nil. Since the processWriteError function is used by many different
+// methods, both *One and *Many, we need a way to differentiate if the method should return
+// the result and the error.
+type returnResult int
+
+const (
+	rrNone returnResult = 1 << iota // None means do not return the result ever.
+	rrOne                           // One means return the result if this was called by a *One method.
+	rrMany                          // Many means return the result is this was called by a *Many method.
+
+	rrAll returnResult = rrOne | rrMany // All means always return the result.
+)
+
+// processWriteError handles processing the result of a write operation. If the retrunResult matches
+// the calling method's type, it should return the result object in addition to the error.
+// This function will wrap the errors from other packages and return them as errors from this package.
+//
+// WriteConcernError will be returned over WriteErrors if both are present.
+func processWriteError(wce *result.WriteConcernError, wes []result.WriteError, err error) (returnResult, error) {
+	switch {
+	case err == command.ErrUnacknowledgedWrite:
+		return rrAll, ErrUnacknowledgedWrite
+	case err != nil:
+		return rrNone, replaceTopologyErr(err)
+	case wce != nil || len(wes) > 0:
+		return rrMany, WriteException{
+			WriteConcernError: convertWriteConcernError(wce),
+			WriteErrors:       writeErrorsFromResult(wes),
+		}
+	default:
+		return rrAll, nil
+	}
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/index_options_builder.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/index_options_builder.go
new file mode 100644
index 0000000..abc1514
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/index_options_builder.go
@@ -0,0 +1,134 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"github.com/mongodb/mongo-go-driver/bson"
+)
+
+// IndexOptionsBuilder constructs a BSON document for index options
+type IndexOptionsBuilder struct {
+	document bson.D
+}
+
+// NewIndexOptionsBuilder creates a new instance of IndexOptionsBuilder
+func NewIndexOptionsBuilder() *IndexOptionsBuilder {
+	return &IndexOptionsBuilder{}
+}
+
+// Background sets the background option
+func (iob *IndexOptionsBuilder) Background(background bool) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"background", background})
+	return iob
+}
+
+// ExpireAfterSeconds sets the expireAfterSeconds option
+func (iob *IndexOptionsBuilder) ExpireAfterSeconds(expireAfterSeconds int32) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"expireAfterSeconds", expireAfterSeconds})
+	return iob
+}
+
+// Name sets the name option
+func (iob *IndexOptionsBuilder) Name(name string) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"name", name})
+	return iob
+}
+
+// Sparse sets the sparse option
+func (iob *IndexOptionsBuilder) Sparse(sparse bool) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"sparse", sparse})
+	return iob
+}
+
+// StorageEngine sets the storageEngine option
+func (iob *IndexOptionsBuilder) StorageEngine(storageEngine interface{}) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"storageEngine", storageEngine})
+	return iob
+}
+
+// Unique sets the unique option
+func (iob *IndexOptionsBuilder) Unique(unique bool) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"unique", unique})
+	return iob
+}
+
+// Version sets the version option
+func (iob *IndexOptionsBuilder) Version(version int32) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"v", version})
+	return iob
+}
+
+// DefaultLanguage sets the defaultLanguage option
+func (iob *IndexOptionsBuilder) DefaultLanguage(defaultLanguage string) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"default_language", defaultLanguage})
+	return iob
+}
+
+// LanguageOverride sets the languageOverride option
+func (iob *IndexOptionsBuilder) LanguageOverride(languageOverride string) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"language_override", languageOverride})
+	return iob
+}
+
+// TextVersion sets the textVersion option
+func (iob *IndexOptionsBuilder) TextVersion(textVersion int32) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"textIndexVersion", textVersion})
+	return iob
+}
+
+// Weights sets the weights option
+func (iob *IndexOptionsBuilder) Weights(weights interface{}) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"weights", weights})
+	return iob
+}
+
+// SphereVersion sets the sphereVersion option
+func (iob *IndexOptionsBuilder) SphereVersion(sphereVersion int32) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"2dsphereIndexVersion", sphereVersion})
+	return iob
+}
+
+// Bits sets the bits option
+func (iob *IndexOptionsBuilder) Bits(bits int32) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"bits", bits})
+	return iob
+}
+
+// Max sets the max option
+func (iob *IndexOptionsBuilder) Max(max float64) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"max", max})
+	return iob
+}
+
+// Min sets the min option
+func (iob *IndexOptionsBuilder) Min(min float64) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"min", min})
+	return iob
+}
+
+// BucketSize sets the bucketSize option
+func (iob *IndexOptionsBuilder) BucketSize(bucketSize int32) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"bucketSize", bucketSize})
+	return iob
+}
+
+// PartialFilterExpression sets the partialFilterExpression option
+func (iob *IndexOptionsBuilder) PartialFilterExpression(partialFilterExpression interface{}) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"partialFilterExpression", partialFilterExpression})
+	return iob
+}
+
+// Collation sets the collation option
+func (iob *IndexOptionsBuilder) Collation(collation interface{}) *IndexOptionsBuilder {
+	iob.document = append(iob.document, bson.E{"collation", collation})
+	return iob
+}
+
+// Build returns the BSON document from the builder
+func (iob *IndexOptionsBuilder) Build() bson.D {
+	return iob.document
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/index_view.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/index_view.go
new file mode 100644
index 0000000..1ff8d49
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/index_view.go
@@ -0,0 +1,343 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"bytes"
+	"context"
+	"errors"
+	"fmt"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/x/bsonx"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/description"
+)
+
+// ErrInvalidIndexValue indicates that the index Keys document has a value that isn't either a number or a string.
+var ErrInvalidIndexValue = errors.New("invalid index value")
+
+// ErrNonStringIndexName indicates that the index name specified in the options is not a string.
+var ErrNonStringIndexName = errors.New("index name must be a string")
+
+// ErrMultipleIndexDrop indicates that multiple indexes would be dropped from a call to IndexView.DropOne.
+var ErrMultipleIndexDrop = errors.New("multiple indexes would be dropped")
+
+// IndexView is used to create, drop, and list indexes on a given collection.
+type IndexView struct {
+	coll *Collection
+}
+
+// IndexModel contains information about an index.
+type IndexModel struct {
+	Keys    interface{}
+	Options *options.IndexOptions
+}
+
+// List returns a cursor iterating over all the indexes in the collection.
+func (iv IndexView) List(ctx context.Context, opts ...*options.ListIndexesOptions) (*Cursor, error) {
+	sess := sessionFromContext(ctx)
+
+	err := iv.coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	listCmd := command.ListIndexes{
+		NS:      iv.coll.namespace(),
+		Session: sess,
+		Clock:   iv.coll.client.clock,
+	}
+
+	readSelector := description.CompositeSelector([]description.ServerSelector{
+		description.ReadPrefSelector(readpref.Primary()),
+		description.LatencySelector(iv.coll.client.localThreshold),
+	})
+	batchCursor, err := driver.ListIndexes(
+		ctx, listCmd,
+		iv.coll.client.topology,
+		readSelector,
+		iv.coll.client.id,
+		iv.coll.client.topology.SessionPool,
+		opts...,
+	)
+	if err != nil {
+		if err == command.ErrEmptyCursor {
+			return newEmptyCursor(), nil
+		}
+		return nil, replaceTopologyErr(err)
+	}
+
+	cursor, err := newCursor(batchCursor, iv.coll.registry)
+	return cursor, replaceTopologyErr(err)
+}
+
+// CreateOne creates a single index in the collection specified by the model.
+func (iv IndexView) CreateOne(ctx context.Context, model IndexModel, opts ...*options.CreateIndexesOptions) (string, error) {
+	names, err := iv.CreateMany(ctx, []IndexModel{model}, opts...)
+	if err != nil {
+		return "", err
+	}
+
+	return names[0], nil
+}
+
+// CreateMany creates multiple indexes in the collection specified by the models. The names of the
+// creates indexes are returned.
+func (iv IndexView) CreateMany(ctx context.Context, models []IndexModel, opts ...*options.CreateIndexesOptions) ([]string, error) {
+	names := make([]string, 0, len(models))
+	indexes := bsonx.Arr{}
+
+	for _, model := range models {
+		if model.Keys == nil {
+			return nil, fmt.Errorf("index model keys cannot be nil")
+		}
+
+		name, err := getOrGenerateIndexName(iv.coll.registry, model)
+		if err != nil {
+			return nil, err
+		}
+
+		names = append(names, name)
+
+		keys, err := transformDocument(iv.coll.registry, model.Keys)
+		if err != nil {
+			return nil, err
+		}
+		index := bsonx.Doc{{"key", bsonx.Document(keys)}}
+		if model.Options != nil {
+			optsDoc, err := iv.createOptionsDoc(model.Options)
+			if err != nil {
+				return nil, err
+			}
+
+			index = append(index, optsDoc...)
+		}
+		index = index.Set("name", bsonx.String(name))
+
+		indexes = append(indexes, bsonx.Document(index))
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := iv.coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	cmd := command.CreateIndexes{
+		NS:      iv.coll.namespace(),
+		Indexes: indexes,
+		Session: sess,
+		Clock:   iv.coll.client.clock,
+	}
+
+	_, err = driver.CreateIndexes(
+		ctx, cmd,
+		iv.coll.client.topology,
+		iv.coll.writeSelector,
+		iv.coll.client.id,
+		iv.coll.client.topology.SessionPool,
+		opts...,
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	return names, nil
+}
+
+func (iv IndexView) createOptionsDoc(opts *options.IndexOptions) (bsonx.Doc, error) {
+	optsDoc := bsonx.Doc{}
+	if opts.Background != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"background", bsonx.Boolean(*opts.Background)})
+	}
+	if opts.ExpireAfterSeconds != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"expireAfterSeconds", bsonx.Int32(*opts.ExpireAfterSeconds)})
+	}
+	if opts.Name != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"name", bsonx.String(*opts.Name)})
+	}
+	if opts.Sparse != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"sparse", bsonx.Boolean(*opts.Sparse)})
+	}
+	if opts.StorageEngine != nil {
+		doc, err := transformDocument(iv.coll.registry, opts.StorageEngine)
+		if err != nil {
+			return nil, err
+		}
+
+		optsDoc = append(optsDoc, bsonx.Elem{"storageEngine", bsonx.Document(doc)})
+	}
+	if opts.Unique != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"unique", bsonx.Boolean(*opts.Unique)})
+	}
+	if opts.Version != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"v", bsonx.Int32(*opts.Version)})
+	}
+	if opts.DefaultLanguage != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"default_language", bsonx.String(*opts.DefaultLanguage)})
+	}
+	if opts.LanguageOverride != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"language_override", bsonx.String(*opts.LanguageOverride)})
+	}
+	if opts.TextVersion != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"textIndexVersion", bsonx.Int32(*opts.TextVersion)})
+	}
+	if opts.Weights != nil {
+		weightsDoc, err := transformDocument(iv.coll.registry, opts.Weights)
+		if err != nil {
+			return nil, err
+		}
+
+		optsDoc = append(optsDoc, bsonx.Elem{"weights", bsonx.Document(weightsDoc)})
+	}
+	if opts.SphereVersion != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"2dsphereIndexVersion", bsonx.Int32(*opts.SphereVersion)})
+	}
+	if opts.Bits != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"bits", bsonx.Int32(*opts.Bits)})
+	}
+	if opts.Max != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"max", bsonx.Double(*opts.Max)})
+	}
+	if opts.Min != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"min", bsonx.Double(*opts.Min)})
+	}
+	if opts.BucketSize != nil {
+		optsDoc = append(optsDoc, bsonx.Elem{"bucketSize", bsonx.Int32(*opts.BucketSize)})
+	}
+	if opts.PartialFilterExpression != nil {
+		doc, err := transformDocument(iv.coll.registry, opts.PartialFilterExpression)
+		if err != nil {
+			return nil, err
+		}
+
+		optsDoc = append(optsDoc, bsonx.Elem{"partialFilterExpression", bsonx.Document(doc)})
+	}
+	if opts.Collation != nil {
+		doc := opts.Collation.ToDocument()
+		optsDoc = append(optsDoc, bsonx.Elem{"collation", bsonx.Document(doc)})
+	}
+
+	return optsDoc, nil
+}
+
+// DropOne drops the index with the given name from the collection.
+func (iv IndexView) DropOne(ctx context.Context, name string, opts ...*options.DropIndexesOptions) (bson.Raw, error) {
+	if name == "*" {
+		return nil, ErrMultipleIndexDrop
+	}
+
+	sess := sessionFromContext(ctx)
+
+	err := iv.coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	cmd := command.DropIndexes{
+		NS:      iv.coll.namespace(),
+		Index:   name,
+		Session: sess,
+		Clock:   iv.coll.client.clock,
+	}
+
+	return driver.DropIndexes(
+		ctx, cmd,
+		iv.coll.client.topology,
+		iv.coll.writeSelector,
+		iv.coll.client.id,
+		iv.coll.client.topology.SessionPool,
+		opts...,
+	)
+}
+
+// DropAll drops all indexes in the collection.
+func (iv IndexView) DropAll(ctx context.Context, opts ...*options.DropIndexesOptions) (bson.Raw, error) {
+	sess := sessionFromContext(ctx)
+
+	err := iv.coll.client.ValidSession(sess)
+	if err != nil {
+		return nil, err
+	}
+
+	cmd := command.DropIndexes{
+		NS:      iv.coll.namespace(),
+		Index:   "*",
+		Session: sess,
+		Clock:   iv.coll.client.clock,
+	}
+
+	return driver.DropIndexes(
+		ctx, cmd,
+		iv.coll.client.topology,
+		iv.coll.writeSelector,
+		iv.coll.client.id,
+		iv.coll.client.topology.SessionPool,
+		opts...,
+	)
+}
+
+func getOrGenerateIndexName(registry *bsoncodec.Registry, model IndexModel) (string, error) {
+	if model.Options != nil && model.Options.Name != nil {
+		return *model.Options.Name, nil
+	}
+
+	name := bytes.NewBufferString("")
+	first := true
+
+	keys, err := transformDocument(registry, model.Keys)
+	if err != nil {
+		return "", err
+	}
+	for _, elem := range keys {
+		if !first {
+			_, err := name.WriteRune('_')
+			if err != nil {
+				return "", err
+			}
+		}
+
+		_, err := name.WriteString(elem.Key)
+		if err != nil {
+			return "", err
+		}
+
+		_, err = name.WriteRune('_')
+		if err != nil {
+			return "", err
+		}
+
+		var value string
+
+		switch elem.Value.Type() {
+		case bsontype.Int32:
+			value = fmt.Sprintf("%d", elem.Value.Int32())
+		case bsontype.Int64:
+			value = fmt.Sprintf("%d", elem.Value.Int64())
+		case bsontype.String:
+			value = elem.Value.StringValue()
+		default:
+			return "", ErrInvalidIndexValue
+		}
+
+		_, err = name.WriteString(value)
+		if err != nil {
+			return "", err
+		}
+
+		first = false
+	}
+
+	return name.String(), nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/mongo.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/mongo.go
new file mode 100644
index 0000000..9757d9b
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/mongo.go
@@ -0,0 +1,242 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net"
+	"reflect"
+	"strings"
+
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/x/bsonx"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+	"github.com/mongodb/mongo-go-driver/bson/primitive"
+)
+
+// Dialer is used to make network connections.
+type Dialer interface {
+	DialContext(ctx context.Context, network, address string) (net.Conn, error)
+}
+
+// BSONAppender is an interface implemented by types that can marshal a
+// provided type into BSON bytes and append those bytes to the provided []byte.
+// The AppendBSON can return a non-nil error and non-nil []byte. The AppendBSON
+// method may also write incomplete BSON to the []byte.
+type BSONAppender interface {
+	AppendBSON([]byte, interface{}) ([]byte, error)
+}
+
+// BSONAppenderFunc is an adapter function that allows any function that
+// satisfies the AppendBSON method signature to be used where a BSONAppender is
+// used.
+type BSONAppenderFunc func([]byte, interface{}) ([]byte, error)
+
+// AppendBSON implements the BSONAppender interface
+func (baf BSONAppenderFunc) AppendBSON(dst []byte, val interface{}) ([]byte, error) {
+	return baf(dst, val)
+}
+
+// MarshalError is returned when attempting to transform a value into a document
+// results in an error.
+type MarshalError struct {
+	Value interface{}
+	Err   error
+}
+
+// Error implements the error interface.
+func (me MarshalError) Error() string {
+	return fmt.Sprintf("cannot transform type %s to a *bsonx.Document", reflect.TypeOf(me.Value))
+}
+
+// Pipeline is a type that makes creating aggregation pipelines easier. It is a
+// helper and is intended for serializing to BSON.
+//
+// Example usage:
+//
+//		mongo.Pipeline{
+//			{{"$group", bson.D{{"_id", "$state"}, {"totalPop", bson.D{{"$sum", "$pop"}}}}}},
+//			{{"$match", bson.D{{"totalPop", bson.D{{"$gte", 10*1000*1000}}}}}},
+//		}
+//
+type Pipeline []bson.D
+
+// transformAndEnsureID is a hack that makes it easy to get a RawValue as the _id value. This will
+// be removed when we switch from using bsonx to bsoncore for the driver package.
+func transformAndEnsureID(registry *bsoncodec.Registry, val interface{}) (bsonx.Doc, interface{}, error) {
+	// TODO: performance is going to be pretty bad for bsonx.Doc here since we turn it into a []byte
+	// only to turn it back into a bsonx.Doc. We can fix this post beta1 when we refactor the driver
+	// package to use bsoncore.Document instead of bsonx.Doc.
+	if registry == nil {
+		registry = bson.NewRegistryBuilder().Build()
+	}
+	switch tt := val.(type) {
+	case nil:
+		return nil, nil, ErrNilDocument
+	case bsonx.Doc:
+		val = tt.Copy()
+	case []byte:
+		// Slight optimization so we'll just use MarshalBSON and not go through the codec machinery.
+		val = bson.Raw(tt)
+	}
+
+	// TODO(skriptble): Use a pool of these instead.
+	buf := make([]byte, 0, 256)
+	b, err := bson.MarshalAppendWithRegistry(registry, buf, val)
+	if err != nil {
+		return nil, nil, MarshalError{Value: val, Err: err}
+	}
+
+	d, err := bsonx.ReadDoc(b)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var id interface{}
+
+	idx := d.IndexOf("_id")
+	var idElem bsonx.Elem
+	switch idx {
+	case -1:
+		idElem = bsonx.Elem{"_id", bsonx.ObjectID(primitive.NewObjectID())}
+		d = append(d, bsonx.Elem{})
+		copy(d[1:], d)
+		d[0] = idElem
+	default:
+		idElem = d[idx]
+		copy(d[1:idx+1], d[0:idx])
+		d[0] = idElem
+	}
+
+	t, data, err := idElem.Value.MarshalAppendBSONValue(buf[:0])
+	if err != nil {
+		return nil, nil, err
+	}
+
+	err = bson.RawValue{Type: t, Value: data}.UnmarshalWithRegistry(registry, &id)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return d, id, nil
+}
+
+func transformDocument(registry *bsoncodec.Registry, val interface{}) (bsonx.Doc, error) {
+	if registry == nil {
+		registry = bson.NewRegistryBuilder().Build()
+	}
+	if val == nil {
+		return nil, ErrNilDocument
+	}
+	if doc, ok := val.(bsonx.Doc); ok {
+		return doc.Copy(), nil
+	}
+	if bs, ok := val.([]byte); ok {
+		// Slight optimization so we'll just use MarshalBSON and not go through the codec machinery.
+		val = bson.Raw(bs)
+	}
+
+	// TODO(skriptble): Use a pool of these instead.
+	buf := make([]byte, 0, 256)
+	b, err := bson.MarshalAppendWithRegistry(registry, buf[:0], val)
+	if err != nil {
+		return nil, MarshalError{Value: val, Err: err}
+	}
+	return bsonx.ReadDoc(b)
+}
+
+func ensureID(d bsonx.Doc) (bsonx.Doc, interface{}) {
+	var id interface{}
+
+	elem, err := d.LookupElementErr("_id")
+	switch err.(type) {
+	case nil:
+		id = elem
+	default:
+		oid := primitive.NewObjectID()
+		d = append(d, bsonx.Elem{"_id", bsonx.ObjectID(oid)})
+		id = oid
+	}
+	return d, id
+}
+
+func ensureDollarKey(doc bsonx.Doc) error {
+	if len(doc) == 0 {
+		return errors.New("update document must have at least one element")
+	}
+	if !strings.HasPrefix(doc[0].Key, "$") {
+		return errors.New("update document must contain key beginning with '$'")
+	}
+	return nil
+}
+
+func transformAggregatePipeline(registry *bsoncodec.Registry, pipeline interface{}) (bsonx.Arr, error) {
+	pipelineArr := bsonx.Arr{}
+	switch t := pipeline.(type) {
+	case bsoncodec.ValueMarshaler:
+		btype, val, err := t.MarshalBSONValue()
+		if err != nil {
+			return nil, err
+		}
+		if btype != bsontype.Array {
+			return nil, fmt.Errorf("ValueMarshaler returned a %v, but was expecting %v", btype, bsontype.Array)
+		}
+		err = pipelineArr.UnmarshalBSONValue(btype, val)
+		if err != nil {
+			return nil, err
+		}
+	default:
+		val := reflect.ValueOf(t)
+		if !val.IsValid() || (val.Kind() != reflect.Slice && val.Kind() != reflect.Array) {
+			return nil, fmt.Errorf("can only transform slices and arrays into aggregation pipelines, but got %v", val.Kind())
+		}
+		for idx := 0; idx < val.Len(); idx++ {
+			elem, err := transformDocument(registry, val.Index(idx).Interface())
+			if err != nil {
+				return nil, err
+			}
+			pipelineArr = append(pipelineArr, bsonx.Document(elem))
+		}
+	}
+
+	return pipelineArr, nil
+}
+
+// Build the aggregation pipeline for the CountDocument command.
+func countDocumentsAggregatePipeline(registry *bsoncodec.Registry, filter interface{}, opts *options.CountOptions) (bsonx.Arr, error) {
+	pipeline := bsonx.Arr{}
+	filterDoc, err := transformDocument(registry, filter)
+
+	if err != nil {
+		return nil, err
+	}
+	pipeline = append(pipeline, bsonx.Document(bsonx.Doc{{"$match", bsonx.Document(filterDoc)}}))
+
+	if opts != nil {
+		if opts.Skip != nil {
+			pipeline = append(pipeline, bsonx.Document(bsonx.Doc{{"$skip", bsonx.Int64(*opts.Skip)}}))
+		}
+		if opts.Limit != nil {
+			pipeline = append(pipeline, bsonx.Document(bsonx.Doc{{"$limit", bsonx.Int64(*opts.Limit)}}))
+		}
+	}
+
+	pipeline = append(pipeline, bsonx.Document(bsonx.Doc{
+		{"$group", bsonx.Document(bsonx.Doc{
+			{"_id", bsonx.Null()},
+			{"n", bsonx.Document(bsonx.Doc{{"$sum", bsonx.Int32(1)}})},
+		})},
+	},
+	))
+
+	return pipeline, nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/aggregateoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/aggregateoptions.go
new file mode 100644
index 0000000..3700d84
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/aggregateoptions.go
@@ -0,0 +1,119 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import "time"
+
+// AggregateOptions represents all possible options to the aggregate() function
+type AggregateOptions struct {
+	AllowDiskUse             *bool          // Enables writing to temporary files. When set to true, aggregation stages can write data to the _tmp subdirectory in the dbPath directory
+	BatchSize                *int32         // The number of documents to return per batch
+	BypassDocumentValidation *bool          // If true, allows the write to opt-out of document level validation. This only applies when the $out stage is specified
+	Collation                *Collation     // Specifies a collation
+	MaxTime                  *time.Duration // The maximum amount of time to allow the query to run
+	MaxAwaitTime             *time.Duration // The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query
+	Comment                  *string        // Enables users to specify an arbitrary string to help trace the operation through the database profiler, currentOp and logs.
+	Hint                     interface{}    // The index to use for the aggregation. The hint does not apply to $lookup and $graphLookup stages
+}
+
+// Aggregate returns a pointer to a new AggregateOptions
+func Aggregate() *AggregateOptions {
+	return &AggregateOptions{}
+}
+
+// SetAllowDiskUse enables writing to temporary files. When set to true,
+// aggregation stages can write data to the _tmp subdirectory in the
+// dbPath directory
+func (ao *AggregateOptions) SetAllowDiskUse(b bool) *AggregateOptions {
+	ao.AllowDiskUse = &b
+	return ao
+}
+
+// SetBatchSize specifies the number of documents to return per batch
+func (ao *AggregateOptions) SetBatchSize(i int32) *AggregateOptions {
+	ao.BatchSize = &i
+	return ao
+}
+
+// SetBypassDocumentValidation allows the write to opt-out of document level
+// validation. This only applies when the $out stage is specified
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (ao *AggregateOptions) SetBypassDocumentValidation(b bool) *AggregateOptions {
+	ao.BypassDocumentValidation = &b
+	return ao
+}
+
+// SetCollation specifies a collation.
+// Valid for server versions >= 3.4
+func (ao *AggregateOptions) SetCollation(c *Collation) *AggregateOptions {
+	ao.Collation = c
+	return ao
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the query to run
+func (ao *AggregateOptions) SetMaxTime(d time.Duration) *AggregateOptions {
+	ao.MaxTime = &d
+	return ao
+}
+
+// SetMaxAwaitTime specifies the maximum amount of time for the server to
+// wait on new documents to satisfy a tailable cursor query
+// For servers < 3.2, this option is ignored
+func (ao *AggregateOptions) SetMaxAwaitTime(d time.Duration) *AggregateOptions {
+	ao.MaxAwaitTime = &d
+	return ao
+}
+
+// SetComment enables users to specify an arbitrary string to help trace the
+// operation through the database profiler, currentOp and logs.
+func (ao *AggregateOptions) SetComment(s string) *AggregateOptions {
+	ao.Comment = &s
+	return ao
+}
+
+// SetHint specifies the index to use for the aggregation. The hint does not
+// apply to $lookup and $graphLookup stages
+func (ao *AggregateOptions) SetHint(h interface{}) *AggregateOptions {
+	ao.Hint = h
+	return ao
+}
+
+// MergeAggregateOptions combines the argued AggregateOptions into a single AggregateOptions in a last-one-wins fashion
+func MergeAggregateOptions(opts ...*AggregateOptions) *AggregateOptions {
+	aggOpts := Aggregate()
+	for _, ao := range opts {
+		if ao == nil {
+			continue
+		}
+		if ao.AllowDiskUse != nil {
+			aggOpts.AllowDiskUse = ao.AllowDiskUse
+		}
+		if ao.BatchSize != nil {
+			aggOpts.BatchSize = ao.BatchSize
+		}
+		if ao.BypassDocumentValidation != nil {
+			aggOpts.BypassDocumentValidation = ao.BypassDocumentValidation
+		}
+		if ao.Collation != nil {
+			aggOpts.Collation = ao.Collation
+		}
+		if ao.MaxTime != nil {
+			aggOpts.MaxTime = ao.MaxTime
+		}
+		if ao.MaxAwaitTime != nil {
+			aggOpts.MaxAwaitTime = ao.MaxAwaitTime
+		}
+		if ao.Comment != nil {
+			aggOpts.Comment = ao.Comment
+		}
+		if ao.Hint != nil {
+			aggOpts.Hint = ao.Hint
+		}
+	}
+
+	return aggOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/bulkwriteoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/bulkwriteoptions.go
new file mode 100644
index 0000000..86282fa
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/bulkwriteoptions.go
@@ -0,0 +1,55 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// DefaultOrdered is the default order for a BulkWriteOptions struct created from BulkWrite.
+var DefaultOrdered = true
+
+// BulkWriteOptions represent all possible options for a bulkWrite operation.
+type BulkWriteOptions struct {
+	BypassDocumentValidation *bool // If true, allows the write to opt out of document-level validation.
+	Ordered                  *bool // If true, when a write fails, return without performing remaining writes. Defaults to true.
+}
+
+// BulkWrite creates a new *BulkWriteOptions
+func BulkWrite() *BulkWriteOptions {
+	return &BulkWriteOptions{
+		Ordered: &DefaultOrdered,
+	}
+}
+
+// SetOrdered configures the ordered option. If true, when a write fails, the function will return without attempting
+// remaining writes. Defaults to true.
+func (b *BulkWriteOptions) SetOrdered(ordered bool) *BulkWriteOptions {
+	b.Ordered = &ordered
+	return b
+}
+
+// SetBypassDocumentValidation specifies if the write should opt out of document-level validation.
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (b *BulkWriteOptions) SetBypassDocumentValidation(bypass bool) *BulkWriteOptions {
+	b.BypassDocumentValidation = &bypass
+	return b
+}
+
+// MergeBulkWriteOptions combines the given *BulkWriteOptions into a single *BulkWriteOptions in a last one wins fashion.
+func MergeBulkWriteOptions(opts ...*BulkWriteOptions) *BulkWriteOptions {
+	b := BulkWrite()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.Ordered != nil {
+			b.Ordered = opt.Ordered
+		}
+		if opt.BypassDocumentValidation != nil {
+			b.BypassDocumentValidation = opt.BypassDocumentValidation
+		}
+	}
+
+	return b
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/changestreamoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/changestreamoptions.go
new file mode 100644
index 0000000..c8776ac
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/changestreamoptions.go
@@ -0,0 +1,97 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"github.com/mongodb/mongo-go-driver/bson/primitive"
+	"time"
+)
+
+// ChangeStreamOptions represents all possible options to a change stream
+type ChangeStreamOptions struct {
+	BatchSize            *int32               // The number of documents to return per batch
+	Collation            *Collation           // Specifies a collation
+	FullDocument         *FullDocument        // When set to ‘updateLookup’, the change notification for partial updates will include both a delta describing the changes to the document, as well as a copy of the entire document that was changed from some time after the change occurred.
+	MaxAwaitTime         *time.Duration       // The maximum amount of time for the server to wait on new documents to satisfy a change stream query
+	ResumeAfter          interface{}          // Specifies the logical starting point for the new change stream
+	StartAtOperationTime *primitive.Timestamp // Ensures that a change stream will only provide changes that occurred after a timestamp.
+}
+
+// ChangeStream returns a pointer to a new ChangeStreamOptions
+func ChangeStream() *ChangeStreamOptions {
+	return &ChangeStreamOptions{}
+}
+
+// SetBatchSize specifies the number of documents to return per batch
+func (cso *ChangeStreamOptions) SetBatchSize(i int32) *ChangeStreamOptions {
+	cso.BatchSize = &i
+	return cso
+}
+
+// SetCollation specifies a collation
+func (cso *ChangeStreamOptions) SetCollation(c Collation) *ChangeStreamOptions {
+	cso.Collation = &c
+	return cso
+}
+
+// SetFullDocument specifies the fullDocument option.
+// When set to ‘updateLookup’, the change notification for partial updates will
+// include both a delta describing the changes to the document, as well as a
+// copy of the entire document that was changed from some time after the change
+// occurred.
+func (cso *ChangeStreamOptions) SetFullDocument(fd FullDocument) *ChangeStreamOptions {
+	cso.FullDocument = &fd
+	return cso
+}
+
+// SetMaxAwaitTime specifies the maximum amount of time for the server to wait on new documents to satisfy a change stream query
+func (cso *ChangeStreamOptions) SetMaxAwaitTime(d time.Duration) *ChangeStreamOptions {
+	cso.MaxAwaitTime = &d
+	return cso
+}
+
+// SetResumeAfter specifies the logical starting point for the new change stream
+func (cso *ChangeStreamOptions) SetResumeAfter(rt interface{}) *ChangeStreamOptions {
+	cso.ResumeAfter = rt
+	return cso
+}
+
+// SetStartAtOperationTime ensures that a change stream will only provide changes that occurred after a specified timestamp.
+func (cso *ChangeStreamOptions) SetStartAtOperationTime(t *primitive.Timestamp) *ChangeStreamOptions {
+	cso.StartAtOperationTime = t
+	return cso
+}
+
+// MergeChangeStreamOptions combines the argued ChangeStreamOptions into a single ChangeStreamOptions in a last-one-wins fashion
+func MergeChangeStreamOptions(opts ...*ChangeStreamOptions) *ChangeStreamOptions {
+	csOpts := ChangeStream()
+	for _, cso := range opts {
+		if cso == nil {
+			continue
+		}
+		if cso.BatchSize != nil {
+			csOpts.BatchSize = cso.BatchSize
+		}
+		if cso.Collation != nil {
+			csOpts.Collation = cso.Collation
+		}
+		if cso.FullDocument != nil {
+			csOpts.FullDocument = cso.FullDocument
+		}
+		if cso.MaxAwaitTime != nil {
+			csOpts.MaxAwaitTime = cso.MaxAwaitTime
+		}
+		if cso.ResumeAfter != nil {
+			csOpts.ResumeAfter = cso.ResumeAfter
+		}
+		if cso.StartAtOperationTime != nil {
+			csOpts.StartAtOperationTime = cso.StartAtOperationTime
+		}
+	}
+
+	return csOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/clientoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/clientoptions.go
new file mode 100644
index 0000000..e09a9c1
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/clientoptions.go
@@ -0,0 +1,424 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"context"
+	"net"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/event"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
+	"github.com/mongodb/mongo-go-driver/x/network/connection"
+	"github.com/mongodb/mongo-go-driver/x/network/connstring"
+)
+
+// ContextDialer makes new network connections
+type ContextDialer interface {
+	DialContext(ctx context.Context, network, address string) (net.Conn, error)
+}
+
+// SSLOpt holds client SSL options.
+//
+// Enabled indicates whether SSL should be enabled.
+//
+// ClientCertificateKeyFile specifies the file containing the client certificate and private key
+// used for authentication.
+//
+// ClientCertificateKeyPassword provides a callback that returns a password used for decrypting the
+// private key of a PEM file (if one is provided).
+//
+// Insecure indicates whether to skip the verification of the server certificate and hostname.
+//
+// CaFile specifies the file containing the certificate authority used for SSL connections.
+type SSLOpt struct {
+	Enabled                      bool
+	ClientCertificateKeyFile     string
+	ClientCertificateKeyPassword func() string
+	Insecure                     bool
+	CaFile                       string
+}
+
+// Credential holds auth options.
+//
+// AuthMechanism indicates the mechanism to use for authentication.
+// Supported values include "SCRAM-SHA-256", "SCRAM-SHA-1", "MONGODB-CR", "PLAIN", "GSSAPI", and "MONGODB-X509".
+//
+// AuthMechanismProperties specifies additional configuration options which may be used by certain
+// authentication mechanisms.
+//
+// AuthSource specifies the database to authenticate against.
+//
+// Username specifies the username that will be authenticated.
+//
+// Password specifies the password used for authentication.
+type Credential struct {
+	AuthMechanism           string
+	AuthMechanismProperties map[string]string
+	AuthSource              string
+	Username                string
+	Password                string
+}
+
+// ClientOptions represents all possbile options to configure a client.
+type ClientOptions struct {
+	TopologyOptions []topology.Option
+	ConnString      connstring.ConnString
+	RetryWrites     *bool
+	ReadPreference  *readpref.ReadPref
+	ReadConcern     *readconcern.ReadConcern
+	WriteConcern    *writeconcern.WriteConcern
+	Registry        *bsoncodec.Registry
+}
+
+// Client creates a new ClientOptions instance.
+func Client() *ClientOptions {
+	return &ClientOptions{
+		TopologyOptions: make([]topology.Option, 0),
+	}
+}
+
+// SetAppName specifies the client application name. This value is used by MongoDB when it logs
+// connection information and profile information, such as slow queries.
+func (c *ClientOptions) SetAppName(s string) *ClientOptions {
+	c.ConnString.AppName = s
+
+	return c
+}
+
+// SetAuth sets the authentication options.
+func (c *ClientOptions) SetAuth(auth Credential) *ClientOptions {
+	c.ConnString.AuthMechanism = auth.AuthMechanism
+	c.ConnString.AuthMechanismProperties = auth.AuthMechanismProperties
+	c.ConnString.AuthSource = auth.AuthSource
+	c.ConnString.Username = auth.Username
+	c.ConnString.Password = auth.Password
+
+	return c
+}
+
+// SetConnectTimeout specifies the timeout for an initial connection to a server.
+// If a custom Dialer is used, this method won't be set and the user is
+// responsible for setting the ConnectTimeout for connections on the dialer
+// themselves.
+func (c *ClientOptions) SetConnectTimeout(d time.Duration) *ClientOptions {
+	c.ConnString.ConnectTimeout = d
+	c.ConnString.ConnectTimeoutSet = true
+
+	return c
+}
+
+// SetDialer specifies a custom dialer used to dial new connections to a server.
+// If a custom dialer is not set, a net.Dialer with a 300 second keepalive time will be used by default.
+func (c *ClientOptions) SetDialer(d ContextDialer) *ClientOptions {
+	c.TopologyOptions = append(
+		c.TopologyOptions,
+		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
+			return append(
+				opts,
+				topology.WithConnectionOptions(func(opts ...connection.Option) []connection.Option {
+					return append(
+						opts,
+						connection.WithDialer(func(connection.Dialer) connection.Dialer {
+							return d
+						}),
+					)
+				}),
+			)
+		}),
+	)
+
+	return c
+}
+
+// SetMonitor specifies a command monitor used to see commands for a client.
+func (c *ClientOptions) SetMonitor(m *event.CommandMonitor) *ClientOptions {
+	c.TopologyOptions = append(
+		c.TopologyOptions,
+		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
+			return append(
+				opts,
+				topology.WithConnectionOptions(func(opts ...connection.Option) []connection.Option {
+					return append(
+						opts,
+						connection.WithMonitor(func(*event.CommandMonitor) *event.CommandMonitor {
+							return m
+						}),
+					)
+				}),
+			)
+		}),
+	)
+
+	return c
+}
+
+// SetHeartbeatInterval specifies the interval to wait between server monitoring checks.
+func (c *ClientOptions) SetHeartbeatInterval(d time.Duration) *ClientOptions {
+	c.ConnString.HeartbeatInterval = d
+	c.ConnString.HeartbeatIntervalSet = true
+
+	return c
+}
+
+// SetHosts specifies the initial list of addresses from which to discover the rest of the cluster.
+func (c *ClientOptions) SetHosts(s []string) *ClientOptions {
+	c.ConnString.Hosts = s
+
+	return c
+}
+
+// SetLocalThreshold specifies how far to distribute queries, beyond the server with the fastest
+// round-trip time. If a server's roundtrip time is more than LocalThreshold slower than the
+// the fastest, the driver will not send queries to that server.
+func (c *ClientOptions) SetLocalThreshold(d time.Duration) *ClientOptions {
+	c.ConnString.LocalThreshold = d
+	c.ConnString.LocalThresholdSet = true
+
+	return c
+}
+
+// SetMaxConnIdleTime specifies the maximum number of milliseconds that a connection can remain idle
+// in a connection pool before being removed and closed.
+func (c *ClientOptions) SetMaxConnIdleTime(d time.Duration) *ClientOptions {
+	c.ConnString.MaxConnIdleTime = d
+	c.ConnString.MaxConnIdleTimeSet = true
+
+	return c
+}
+
+// SetMaxPoolSize specifies the max size of a server's connection pool.
+func (c *ClientOptions) SetMaxPoolSize(u uint16) *ClientOptions {
+	c.ConnString.MaxPoolSize = u
+	c.ConnString.MaxPoolSizeSet = true
+
+	return c
+}
+
+// SetReadConcern specifies the read concern.
+func (c *ClientOptions) SetReadConcern(rc *readconcern.ReadConcern) *ClientOptions {
+	c.ReadConcern = rc
+
+	return c
+}
+
+// SetReadPreference specifies the read preference.
+func (c *ClientOptions) SetReadPreference(rp *readpref.ReadPref) *ClientOptions {
+	c.ReadPreference = rp
+
+	return c
+}
+
+// SetRegistry specifies the bsoncodec.Registry.
+func (c *ClientOptions) SetRegistry(registry *bsoncodec.Registry) *ClientOptions {
+	c.Registry = registry
+
+	// add registry to the server options so that it will be used for the cursors built by this client
+	c.TopologyOptions = append(
+		c.TopologyOptions,
+		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
+			return append(
+				opts,
+				topology.WithRegistry(func(*bsoncodec.Registry) *bsoncodec.Registry {
+					return registry
+				}),
+			)
+		}),
+	)
+
+	return c
+}
+
+// SetReplicaSet specifies the name of the replica set of the cluster.
+func (c *ClientOptions) SetReplicaSet(s string) *ClientOptions {
+	c.ConnString.ReplicaSet = s
+
+	return c
+}
+
+// SetRetryWrites specifies whether the client has retryable writes enabled.
+func (c *ClientOptions) SetRetryWrites(b bool) *ClientOptions {
+	c.RetryWrites = &b
+
+	return c
+}
+
+// SetServerSelectionTimeout specifies a timeout in milliseconds to block for server selection.
+func (c *ClientOptions) SetServerSelectionTimeout(d time.Duration) *ClientOptions {
+	c.ConnString.ServerSelectionTimeout = d
+	c.ConnString.ServerSelectionTimeoutSet = true
+
+	return c
+}
+
+// SetSingle specifies whether the driver should connect directly to the server instead of
+// auto-discovering other servers in the cluster.
+func (c *ClientOptions) SetSingle(b bool) *ClientOptions {
+	if b {
+		c.ConnString.Connect = connstring.SingleConnect
+	} else {
+		c.ConnString.Connect = connstring.AutoConnect
+	}
+	c.ConnString.ConnectSet = true
+
+	return c
+}
+
+// SetSocketTimeout specifies the time in milliseconds to attempt to send or receive on a socket
+// before the attempt times out.
+func (c *ClientOptions) SetSocketTimeout(d time.Duration) *ClientOptions {
+	c.ConnString.SocketTimeout = d
+	c.ConnString.SocketTimeoutSet = true
+
+	return c
+}
+
+// SetSSL sets SSL options.
+func (c *ClientOptions) SetSSL(ssl *SSLOpt) *ClientOptions {
+	c.ConnString.SSL = ssl.Enabled
+	c.ConnString.SSLSet = true
+
+	if ssl.ClientCertificateKeyFile != "" {
+		c.ConnString.SSLClientCertificateKeyFile = ssl.ClientCertificateKeyFile
+		c.ConnString.SSLClientCertificateKeyFileSet = true
+	}
+
+	if ssl.ClientCertificateKeyPassword != nil {
+		c.ConnString.SSLClientCertificateKeyPassword = ssl.ClientCertificateKeyPassword
+		c.ConnString.SSLClientCertificateKeyPasswordSet = true
+	}
+
+	c.ConnString.SSLInsecure = ssl.Insecure
+	c.ConnString.SSLInsecureSet = true
+
+	if ssl.CaFile != "" {
+		c.ConnString.SSLCaFile = ssl.CaFile
+		c.ConnString.SSLCaFileSet = true
+	}
+
+	return c
+}
+
+// SetWriteConcern sets the write concern.
+func (c *ClientOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *ClientOptions {
+	c.WriteConcern = wc
+
+	return c
+}
+
+// MergeClientOptions combines the given connstring and *ClientOptions into a single *ClientOptions in a last one wins
+// fashion. The given connstring will be used for the default options, which can be overwritten using the given
+// *ClientOptions.
+func MergeClientOptions(cs connstring.ConnString, opts ...*ClientOptions) *ClientOptions {
+	c := Client()
+	c.ConnString = cs
+
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		c.TopologyOptions = append(c.TopologyOptions, opt.TopologyOptions...)
+
+		if an := opt.ConnString.AppName; an != "" {
+			c.ConnString.AppName = an
+		}
+		if am := opt.ConnString.AuthMechanism; len(am) != 0 {
+			c.ConnString.AuthMechanism = am
+		}
+		if amp := opt.ConnString.AuthMechanismProperties; amp != nil {
+			c.ConnString.AuthMechanismProperties = amp
+		}
+		if as := opt.ConnString.AuthSource; len(as) != 0 {
+			c.ConnString.AuthSource = as
+		}
+		if u := opt.ConnString.Username; len(u) != 0 {
+			c.ConnString.Username = u
+		}
+		if p := opt.ConnString.Password; len(p) != 0 {
+			c.ConnString.Password = p
+		}
+		if opt.ConnString.ConnectTimeoutSet {
+			c.ConnString.ConnectTimeoutSet = true
+			c.ConnString.ConnectTimeout = opt.ConnString.ConnectTimeout
+		}
+		if opt.ConnString.HeartbeatIntervalSet {
+			c.ConnString.HeartbeatIntervalSet = true
+			c.ConnString.HeartbeatInterval = opt.ConnString.HeartbeatInterval
+		}
+		if h := opt.ConnString.Hosts; h != nil {
+			c.ConnString.Hosts = h
+		}
+		if opt.ConnString.LocalThresholdSet {
+			c.ConnString.LocalThresholdSet = true
+			c.ConnString.LocalThreshold = opt.ConnString.LocalThreshold
+		}
+		if opt.ConnString.MaxConnIdleTimeSet {
+			c.ConnString.MaxConnIdleTimeSet = true
+			c.ConnString.MaxConnIdleTime = opt.ConnString.MaxConnIdleTime
+		}
+		if opt.ConnString.MaxPoolSizeSet {
+			c.ConnString.MaxPoolSizeSet = true
+			c.ConnString.MaxPoolSize = opt.ConnString.MaxPoolSize
+		}
+		if opt.ReadConcern != nil {
+			c.ReadConcern = opt.ReadConcern
+		}
+		if opt.ReadPreference != nil {
+			c.ReadPreference = opt.ReadPreference
+		}
+		if opt.Registry != nil {
+			c.Registry = opt.Registry
+		}
+		if rs := opt.ConnString.ReplicaSet; rs != "" {
+			c.ConnString.ReplicaSet = rs
+		}
+		if opt.RetryWrites != nil {
+			c.RetryWrites = opt.RetryWrites
+		}
+		if opt.ConnString.ServerSelectionTimeoutSet {
+			c.ConnString.ServerSelectionTimeoutSet = true
+			c.ConnString.ServerSelectionTimeout = opt.ConnString.ServerSelectionTimeout
+		}
+		if opt.ConnString.ConnectSet {
+			c.ConnString.ConnectSet = true
+			c.ConnString.Connect = opt.ConnString.Connect
+		}
+		if opt.ConnString.SocketTimeoutSet {
+			c.ConnString.SocketTimeoutSet = true
+			c.ConnString.SocketTimeout = opt.ConnString.SocketTimeout
+		}
+		if opt.ConnString.SSLSet {
+			c.ConnString.SSLSet = true
+			c.ConnString.SSL = opt.ConnString.SSL
+		}
+		if opt.ConnString.SSLClientCertificateKeyFileSet {
+			c.ConnString.SSLClientCertificateKeyFileSet = true
+			c.ConnString.SSLClientCertificateKeyFile = opt.ConnString.SSLClientCertificateKeyFile
+		}
+		if opt.ConnString.SSLClientCertificateKeyPasswordSet {
+			c.ConnString.SSLClientCertificateKeyPasswordSet = true
+			c.ConnString.SSLClientCertificateKeyPassword = opt.ConnString.SSLClientCertificateKeyPassword
+		}
+		if opt.ConnString.SSLInsecureSet {
+			c.ConnString.SSLInsecureSet = true
+			c.ConnString.SSLInsecure = opt.ConnString.SSLInsecure
+		}
+		if opt.ConnString.SSLCaFileSet {
+			c.ConnString.SSLCaFileSet = true
+			c.ConnString.SSLCaFile = opt.ConnString.SSLCaFile
+		}
+		if opt.WriteConcern != nil {
+			c.WriteConcern = opt.WriteConcern
+		}
+	}
+
+	return c
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/collectionoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/collectionoptions.go
new file mode 100644
index 0000000..3415505
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/collectionoptions.go
@@ -0,0 +1,77 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+)
+
+// CollectionOptions represent all possible options to configure a Collection.
+type CollectionOptions struct {
+	ReadConcern    *readconcern.ReadConcern   // The read concern for operations in the collection.
+	WriteConcern   *writeconcern.WriteConcern // The write concern for operations in the collection.
+	ReadPreference *readpref.ReadPref         // The read preference for operations in the collection.
+	Registry       *bsoncodec.Registry        // The registry to be used to construct BSON encoders and decoders for the collection.
+}
+
+// Collection creates a new CollectionOptions instance
+func Collection() *CollectionOptions {
+	return &CollectionOptions{}
+}
+
+// SetReadConcern sets the read concern for the collection.
+func (c *CollectionOptions) SetReadConcern(rc *readconcern.ReadConcern) *CollectionOptions {
+	c.ReadConcern = rc
+	return c
+}
+
+// SetWriteConcern sets the write concern for the collection.
+func (c *CollectionOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *CollectionOptions {
+	c.WriteConcern = wc
+	return c
+}
+
+// SetReadPreference sets the read preference for the collection.
+func (c *CollectionOptions) SetReadPreference(rp *readpref.ReadPref) *CollectionOptions {
+	c.ReadPreference = rp
+	return c
+}
+
+// SetRegistry sets the bsoncodec Registry for the collection.
+func (c *CollectionOptions) SetRegistry(r *bsoncodec.Registry) *CollectionOptions {
+	c.Registry = r
+	return c
+}
+
+// MergeCollectionOptions combines the *CollectionOptions arguments into a single *CollectionOptions in a last one wins
+// fashion.
+func MergeCollectionOptions(opts ...*CollectionOptions) *CollectionOptions {
+	c := Collection()
+
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.ReadConcern != nil {
+			c.ReadConcern = opt.ReadConcern
+		}
+		if opt.WriteConcern != nil {
+			c.WriteConcern = opt.WriteConcern
+		}
+		if opt.ReadPreference != nil {
+			c.ReadPreference = opt.ReadPreference
+		}
+		if opt.Registry != nil {
+			c.Registry = opt.Registry
+		}
+	}
+
+	return c
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/countoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/countoptions.go
new file mode 100644
index 0000000..be3baab
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/countoptions.go
@@ -0,0 +1,81 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import "time"
+
+// CountOptions represents all possible options to the count() function
+type CountOptions struct {
+	Collation *Collation     // Specifies a collation
+	Hint      interface{}    // The index to use
+	Limit     *int64         // The maximum number of documents to count
+	MaxTime   *time.Duration // The maximum amount of time to allow the operation to run
+	Skip      *int64         // The number of documents to skip before counting
+}
+
+// Count returns a pointer to a new CountOptions
+func Count() *CountOptions {
+	return &CountOptions{}
+}
+
+// SetCollation specifies a collation
+// Valid for server versions >= 3.4
+func (co *CountOptions) SetCollation(c *Collation) *CountOptions {
+	co.Collation = c
+	return co
+}
+
+// SetHint specifies the index to use
+func (co *CountOptions) SetHint(h interface{}) *CountOptions {
+	co.Hint = h
+	return co
+}
+
+// SetLimit specifies the maximum number of documents to count
+func (co *CountOptions) SetLimit(i int64) *CountOptions {
+	co.Limit = &i
+	return co
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the operation to run
+func (co *CountOptions) SetMaxTime(d time.Duration) *CountOptions {
+	co.MaxTime = &d
+	return co
+}
+
+// SetSkip specifies the number of documents to skip before counting
+func (co *CountOptions) SetSkip(i int64) *CountOptions {
+	co.Skip = &i
+	return co
+}
+
+// MergeCountOptions combines the argued CountOptions into a single CountOptions in a last-one-wins fashion
+func MergeCountOptions(opts ...*CountOptions) *CountOptions {
+	countOpts := Count()
+	for _, co := range opts {
+		if co == nil {
+			continue
+		}
+		if co.Collation != nil {
+			countOpts.Collation = co.Collation
+		}
+		if co.Hint != nil {
+			countOpts.Hint = co.Hint
+		}
+		if co.Limit != nil {
+			countOpts.Limit = co.Limit
+		}
+		if co.MaxTime != nil {
+			countOpts.MaxTime = co.MaxTime
+		}
+		if co.Skip != nil {
+			countOpts.Skip = co.Skip
+		}
+	}
+
+	return countOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/dboptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/dboptions.go
new file mode 100644
index 0000000..989cb13
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/dboptions.go
@@ -0,0 +1,77 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+)
+
+// DatabaseOptions represent all possible options to configure a Database.
+type DatabaseOptions struct {
+	ReadConcern    *readconcern.ReadConcern   // The read concern for operations in the database.
+	WriteConcern   *writeconcern.WriteConcern // The write concern for operations in the database.
+	ReadPreference *readpref.ReadPref         // The read preference for operations in the database.
+	Registry       *bsoncodec.Registry        // The registry to be used to construct BSON encoders and decoders for the database.
+}
+
+// Database creates a new DatabaseOptions instance
+func Database() *DatabaseOptions {
+	return &DatabaseOptions{}
+}
+
+// SetReadConcern sets the read concern for the database.
+func (d *DatabaseOptions) SetReadConcern(rc *readconcern.ReadConcern) *DatabaseOptions {
+	d.ReadConcern = rc
+	return d
+}
+
+// SetWriteConcern sets the write concern for the database.
+func (d *DatabaseOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *DatabaseOptions {
+	d.WriteConcern = wc
+	return d
+}
+
+// SetReadPreference sets the read preference for the database.
+func (d *DatabaseOptions) SetReadPreference(rp *readpref.ReadPref) *DatabaseOptions {
+	d.ReadPreference = rp
+	return d
+}
+
+// SetRegistry sets the bsoncodec Registry for the database.
+func (d *DatabaseOptions) SetRegistry(r *bsoncodec.Registry) *DatabaseOptions {
+	d.Registry = r
+	return d
+}
+
+// MergeDatabaseOptions combines the *DatabaseOptions arguments into a single *DatabaseOptions in a last one wins
+// fashion.
+func MergeDatabaseOptions(opts ...*DatabaseOptions) *DatabaseOptions {
+	d := Database()
+
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.ReadConcern != nil {
+			d.ReadConcern = opt.ReadConcern
+		}
+		if opt.WriteConcern != nil {
+			d.WriteConcern = opt.WriteConcern
+		}
+		if opt.ReadPreference != nil {
+			d.ReadPreference = opt.ReadPreference
+		}
+		if opt.Registry != nil {
+			d.Registry = opt.Registry
+		}
+	}
+
+	return d
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/deleteoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/deleteoptions.go
new file mode 100644
index 0000000..919d6b8
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/deleteoptions.go
@@ -0,0 +1,39 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// DeleteOptions represents all possible options to the deleteOne() and deleteMany() functions
+type DeleteOptions struct {
+	Collation *Collation // Specifies a collation
+}
+
+// Delete returns a pointer to a new DeleteOptions
+func Delete() *DeleteOptions {
+	return &DeleteOptions{}
+}
+
+// SetCollation specifies a collation
+// Valid for servers >= 3.4.
+func (do *DeleteOptions) SetCollation(c *Collation) *DeleteOptions {
+	do.Collation = c
+	return do
+}
+
+// MergeDeleteOptions combines the argued DeleteOptions into a single DeleteOptions in a last-one-wins fashion
+func MergeDeleteOptions(opts ...*DeleteOptions) *DeleteOptions {
+	dOpts := Delete()
+	for _, do := range opts {
+		if do == nil {
+			continue
+		}
+		if do.Collation != nil {
+			dOpts.Collation = do.Collation
+		}
+	}
+
+	return dOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/distinctoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/distinctoptions.go
new file mode 100644
index 0000000..3b3f588
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/distinctoptions.go
@@ -0,0 +1,51 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import "time"
+
+// DistinctOptions represents all possible options to the distinct() function
+type DistinctOptions struct {
+	Collation *Collation     // Specifies a collation
+	MaxTime   *time.Duration // The maximum amount of time to allow the operation to run
+}
+
+// Distinct returns a pointer to a new DistinctOptions
+func Distinct() *DistinctOptions {
+	return &DistinctOptions{}
+}
+
+// SetCollation specifies a collation
+// Valid for server versions >= 3.4
+func (do *DistinctOptions) SetCollation(c *Collation) *DistinctOptions {
+	do.Collation = c
+	return do
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the operation to run
+func (do *DistinctOptions) SetMaxTime(d time.Duration) *DistinctOptions {
+	do.MaxTime = &d
+	return do
+}
+
+// MergeDistinctOptions combines the argued DistinctOptions into a single DistinctOptions in a last-one-wins fashion
+func MergeDistinctOptions(opts ...*DistinctOptions) *DistinctOptions {
+	distinctOpts := Distinct()
+	for _, do := range opts {
+		if do == nil {
+			continue
+		}
+		if do.Collation != nil {
+			distinctOpts.Collation = do.Collation
+		}
+		if do.MaxTime != nil {
+			distinctOpts.MaxTime = do.MaxTime
+		}
+	}
+
+	return distinctOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/estimatedcountoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/estimatedcountoptions.go
new file mode 100644
index 0000000..f43bb9f
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/estimatedcountoptions.go
@@ -0,0 +1,42 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import "time"
+
+// EstimatedDocumentCountOptions represents all possible options to the estimatedDocumentCount() function
+type EstimatedDocumentCountOptions struct {
+	MaxTime *time.Duration // The maximum amount of time to allow the operation to run
+}
+
+// EstimatedDocumentCount returns a pointer to a new EstimatedDocumentCountOptions
+func EstimatedDocumentCount() *EstimatedDocumentCountOptions {
+	return &EstimatedDocumentCountOptions{}
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the operation to run
+func (eco *EstimatedDocumentCountOptions) SetMaxTime(d time.Duration) *EstimatedDocumentCountOptions {
+	eco.MaxTime = &d
+	return eco
+}
+
+// MergeEstimatedDocumentCountOptions combines the given *EstimatedDocumentCountOptions into a single
+// *EstimatedDocumentCountOptions in a last one wins fashion.
+func MergeEstimatedDocumentCountOptions(opts ...*EstimatedDocumentCountOptions) *EstimatedDocumentCountOptions {
+	e := EstimatedDocumentCount()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+
+		if opt.MaxTime != nil {
+			e.MaxTime = opt.MaxTime
+		}
+	}
+
+	return e
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/findoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/findoptions.go
new file mode 100644
index 0000000..4ba6133
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/findoptions.go
@@ -0,0 +1,693 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"time"
+)
+
+// FindOptions represent all possible options to the find() function.
+type FindOptions struct {
+	AllowPartialResults *bool          // If true, allows partial results to be returned if some shards are down.
+	BatchSize           *int32         // Specifies the number of documents to return in every batch.
+	Collation           *Collation     // Specifies a collation to be used
+	Comment             *string        // Specifies a string to help trace the operation through the database.
+	CursorType          *CursorType    // Specifies the type of cursor to use
+	Hint                interface{}    // Specifies the index to use.
+	Limit               *int64         // Sets a limit on the number of results to return.
+	Max                 interface{}    // Sets an exclusive upper bound for a specific index
+	MaxAwaitTime        *time.Duration // Specifies the maximum amount of time for the server to wait on new documents.
+	MaxTime             *time.Duration // Specifies the maximum amount of time to allow the query to run.
+	Min                 interface{}    // Specifies the inclusive lower bound for a specific index.
+	NoCursorTimeout     *bool          // If true, prevents cursors from timing out after an inactivity period.
+	OplogReplay         *bool          // Adds an option for internal use only and should not be set.
+	Projection          interface{}    // Limits the fields returned for all documents.
+	ReturnKey           *bool          // If true, only returns index keys for all result documents.
+	ShowRecordID        *bool          // If true, a $recordId field with the record identifier will be added to the returned documents.
+	Skip                *int64         // Specifies the number of documents to skip before returning
+	Snapshot            *bool          // If true, prevents the cursor from returning a document more than once because of an intervening write operation.
+	Sort                interface{}    // Specifies the order in which to return results.
+}
+
+// Find creates a new FindOptions instance.
+func Find() *FindOptions {
+	return &FindOptions{}
+}
+
+// SetAllowPartialResults sets whether partial results can be returned if some shards are down.
+// For server versions < 3.2, this defaults to false.
+func (f *FindOptions) SetAllowPartialResults(b bool) *FindOptions {
+	f.AllowPartialResults = &b
+	return f
+}
+
+// SetBatchSize sets the number of documents to return in each batch.
+func (f *FindOptions) SetBatchSize(i int32) *FindOptions {
+	f.BatchSize = &i
+	return f
+}
+
+// SetCollation specifies a Collation to use for the Find operation.
+// Valid for server versions >= 3.4
+func (f *FindOptions) SetCollation(collation *Collation) *FindOptions {
+	f.Collation = collation
+	return f
+}
+
+// SetComment specifies a string to help trace the operation through the database.
+func (f *FindOptions) SetComment(comment string) *FindOptions {
+	f.Comment = &comment
+	return f
+}
+
+// SetCursorType specifes the type of cursor to use.
+func (f *FindOptions) SetCursorType(ct CursorType) *FindOptions {
+	f.CursorType = &ct
+	return f
+}
+
+// SetHint specifies the index to use.
+func (f *FindOptions) SetHint(hint interface{}) *FindOptions {
+	f.Hint = hint
+	return f
+}
+
+// SetLimit specifies a limit on the number of results.
+// A negative limit implies that only 1 batch should be returned.
+func (f *FindOptions) SetLimit(i int64) *FindOptions {
+	f.Limit = &i
+	return f
+}
+
+// SetMax specifies an exclusive upper bound for a specific index.
+func (f *FindOptions) SetMax(max interface{}) *FindOptions {
+	f.Max = max
+	return f
+}
+
+// SetMaxAwaitTime specifies the max amount of time for the server to wait on new documents.
+// If the cursor type is not TailableAwait, this option is ignored.
+// For server versions < 3.2, this option is ignored.
+func (f *FindOptions) SetMaxAwaitTime(d time.Duration) *FindOptions {
+	f.MaxAwaitTime = &d
+	return f
+}
+
+// SetMaxTime specifies the max time to allow the query to run.
+func (f *FindOptions) SetMaxTime(d time.Duration) *FindOptions {
+	f.MaxTime = &d
+	return f
+}
+
+// SetMin specifies the inclusive lower bound for a specific index.
+func (f *FindOptions) SetMin(min interface{}) *FindOptions {
+	f.Min = min
+	return f
+}
+
+// SetNoCursorTimeout specifies whether or not cursors should time out after a period of inactivity.
+// For server versions < 3.2, this defaults to false.
+func (f *FindOptions) SetNoCursorTimeout(b bool) *FindOptions {
+	f.NoCursorTimeout = &b
+	return f
+}
+
+// SetOplogReplay adds an option for internal use only and should not be set.
+// For server versions < 3.2, this defaults to false.
+func (f *FindOptions) SetOplogReplay(b bool) *FindOptions {
+	f.OplogReplay = &b
+	return f
+}
+
+// SetProjection adds an option to limit the fields returned for all documents.
+func (f *FindOptions) SetProjection(projection interface{}) *FindOptions {
+	f.Projection = projection
+	return f
+}
+
+// SetReturnKey adds an option to only return index keys for all result documents.
+func (f *FindOptions) SetReturnKey(b bool) *FindOptions {
+	f.ReturnKey = &b
+	return f
+}
+
+// SetShowRecordID adds an option to determine whether to return the record identifier for each document.
+// If true, a $recordId field will be added to each returned document.
+func (f *FindOptions) SetShowRecordID(b bool) *FindOptions {
+	f.ShowRecordID = &b
+	return f
+}
+
+// SetSkip specifies the number of documents to skip before returning.
+// For server versions < 3.2, this defaults to 0.
+func (f *FindOptions) SetSkip(i int64) *FindOptions {
+	f.Skip = &i
+	return f
+}
+
+// SetSnapshot prevents the cursor from returning a document more than once because of an intervening write operation.
+func (f *FindOptions) SetSnapshot(b bool) *FindOptions {
+	f.Snapshot = &b
+	return f
+}
+
+// SetSort specifies the order in which to return documents.
+func (f *FindOptions) SetSort(sort interface{}) *FindOptions {
+	f.Sort = sort
+	return f
+}
+
+// MergeFindOptions combines the argued FindOptions into a single FindOptions in a last-one-wins fashion
+func MergeFindOptions(opts ...*FindOptions) *FindOptions {
+	fo := Find()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.AllowPartialResults != nil {
+			fo.AllowPartialResults = opt.AllowPartialResults
+		}
+		if opt.BatchSize != nil {
+			fo.BatchSize = opt.BatchSize
+		}
+		if opt.Collation != nil {
+			fo.Collation = opt.Collation
+		}
+		if opt.Comment != nil {
+			fo.Comment = opt.Comment
+		}
+		if opt.CursorType != nil {
+			fo.CursorType = opt.CursorType
+		}
+		if opt.Hint != nil {
+			fo.Hint = opt.Hint
+		}
+		if opt.Limit != nil {
+			fo.Limit = opt.Limit
+		}
+		if opt.Max != nil {
+			fo.Max = opt.Max
+		}
+		if opt.MaxAwaitTime != nil {
+			fo.MaxAwaitTime = opt.MaxAwaitTime
+		}
+		if opt.MaxTime != nil {
+			fo.MaxTime = opt.MaxTime
+		}
+		if opt.Min != nil {
+			fo.Min = opt.Min
+		}
+		if opt.NoCursorTimeout != nil {
+			fo.NoCursorTimeout = opt.NoCursorTimeout
+		}
+		if opt.OplogReplay != nil {
+			fo.OplogReplay = opt.OplogReplay
+		}
+		if opt.Projection != nil {
+			fo.Projection = opt.Projection
+		}
+		if opt.ReturnKey != nil {
+			fo.ReturnKey = opt.ReturnKey
+		}
+		if opt.ShowRecordID != nil {
+			fo.ShowRecordID = opt.ShowRecordID
+		}
+		if opt.Skip != nil {
+			fo.Skip = opt.Skip
+		}
+		if opt.Snapshot != nil {
+			fo.Snapshot = opt.Snapshot
+		}
+		if opt.Sort != nil {
+			fo.Sort = opt.Sort
+		}
+	}
+
+	return fo
+}
+
+// FindOneOptions represent all possible options to the findOne() function.
+type FindOneOptions struct {
+	AllowPartialResults *bool          // If true, allows partial results to be returned if some shards are down.
+	BatchSize           *int32         // Specifies the number of documents to return in every batch.
+	Collation           *Collation     // Specifies a collation to be used
+	Comment             *string        // Specifies a string to help trace the operation through the database.
+	CursorType          *CursorType    // Specifies the type of cursor to use
+	Hint                interface{}    // Specifies the index to use.
+	Max                 interface{}    // Sets an exclusive upper bound for a specific index
+	MaxAwaitTime        *time.Duration // Specifies the maximum amount of time for the server to wait on new documents.
+	MaxTime             *time.Duration // Specifies the maximum amount of time to allow the query to run.
+	Min                 interface{}    // Specifies the inclusive lower bound for a specific index.
+	NoCursorTimeout     *bool          // If true, prevents cursors from timing out after an inactivity period.
+	OplogReplay         *bool          // Adds an option for internal use only and should not be set.
+	Projection          interface{}    // Limits the fields returned for all documents.
+	ReturnKey           *bool          // If true, only returns index keys for all result documents.
+	ShowRecordID        *bool          // If true, a $recordId field with the record identifier will be added to the returned documents.
+	Skip                *int64         // Specifies the number of documents to skip before returning
+	Snapshot            *bool          // If true, prevents the cursor from returning a document more than once because of an intervening write operation.
+	Sort                interface{}    // Specifies the order in which to return results.
+}
+
+// FindOne creates a new FindOneOptions instance.
+func FindOne() *FindOneOptions {
+	return &FindOneOptions{}
+}
+
+// SetAllowPartialResults sets whether partial results can be returned if some shards are down.
+func (f *FindOneOptions) SetAllowPartialResults(b bool) *FindOneOptions {
+	f.AllowPartialResults = &b
+	return f
+}
+
+// SetBatchSize sets the number of documents to return in each batch.
+func (f *FindOneOptions) SetBatchSize(i int32) *FindOneOptions {
+	f.BatchSize = &i
+	return f
+}
+
+// SetCollation specifies a Collation to use for the Find operation.
+func (f *FindOneOptions) SetCollation(collation *Collation) *FindOneOptions {
+	f.Collation = collation
+	return f
+}
+
+// SetComment specifies a string to help trace the operation through the database.
+func (f *FindOneOptions) SetComment(comment string) *FindOneOptions {
+	f.Comment = &comment
+	return f
+}
+
+// SetCursorType specifes the type of cursor to use.
+func (f *FindOneOptions) SetCursorType(ct CursorType) *FindOneOptions {
+	f.CursorType = &ct
+	return f
+}
+
+// SetHint specifies the index to use.
+func (f *FindOneOptions) SetHint(hint interface{}) *FindOneOptions {
+	f.Hint = hint
+	return f
+}
+
+// SetMax specifies an exclusive upper bound for a specific index.
+func (f *FindOneOptions) SetMax(max interface{}) *FindOneOptions {
+	f.Max = max
+	return f
+}
+
+// SetMaxAwaitTime specifies the max amount of time for the server to wait on new documents.
+// For server versions < 3.2, this option is ignored.
+func (f *FindOneOptions) SetMaxAwaitTime(d time.Duration) *FindOneOptions {
+	f.MaxAwaitTime = &d
+	return f
+}
+
+// SetMaxTime specifies the max time to allow the query to run.
+func (f *FindOneOptions) SetMaxTime(d time.Duration) *FindOneOptions {
+	f.MaxTime = &d
+	return f
+}
+
+// SetMin specifies the inclusive lower bound for a specific index.
+func (f *FindOneOptions) SetMin(min interface{}) *FindOneOptions {
+	f.Min = min
+	return f
+}
+
+// SetNoCursorTimeout specifies whether or not cursors should time out after a period of inactivity.
+func (f *FindOneOptions) SetNoCursorTimeout(b bool) *FindOneOptions {
+	f.NoCursorTimeout = &b
+	return f
+}
+
+// SetOplogReplay adds an option for internal use only and should not be set.
+func (f *FindOneOptions) SetOplogReplay(b bool) *FindOneOptions {
+	f.OplogReplay = &b
+	return f
+}
+
+// SetProjection adds an option to limit the fields returned for all documents.
+func (f *FindOneOptions) SetProjection(projection interface{}) *FindOneOptions {
+	f.Projection = projection
+	return f
+}
+
+// SetReturnKey adds an option to only return index keys for all result documents.
+func (f *FindOneOptions) SetReturnKey(b bool) *FindOneOptions {
+	f.ReturnKey = &b
+	return f
+}
+
+// SetShowRecordID adds an option to determine whether to return the record identifier for each document.
+// If true, a $recordId field will be added to each returned document.
+func (f *FindOneOptions) SetShowRecordID(b bool) *FindOneOptions {
+	f.ShowRecordID = &b
+	return f
+}
+
+// SetSkip specifies the number of documents to skip before returning.
+func (f *FindOneOptions) SetSkip(i int64) *FindOneOptions {
+	f.Skip = &i
+	return f
+}
+
+// SetSnapshot prevents the cursor from returning a document more than once because of an intervening write operation.
+func (f *FindOneOptions) SetSnapshot(b bool) *FindOneOptions {
+	f.Snapshot = &b
+	return f
+}
+
+// SetSort specifies the order in which to return documents.
+func (f *FindOneOptions) SetSort(sort interface{}) *FindOneOptions {
+	f.Sort = sort
+	return f
+}
+
+// MergeFindOneOptions combines the argued FindOneOptions into a single FindOneOptions in a last-one-wins fashion
+func MergeFindOneOptions(opts ...*FindOneOptions) *FindOneOptions {
+	fo := FindOne()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.AllowPartialResults != nil {
+			fo.AllowPartialResults = opt.AllowPartialResults
+		}
+		if opt.BatchSize != nil {
+			fo.BatchSize = opt.BatchSize
+		}
+		if opt.Collation != nil {
+			fo.Collation = opt.Collation
+		}
+		if opt.Comment != nil {
+			fo.Comment = opt.Comment
+		}
+		if opt.CursorType != nil {
+			fo.CursorType = opt.CursorType
+		}
+		if opt.Hint != nil {
+			fo.Hint = opt.Hint
+		}
+		if opt.Max != nil {
+			fo.Max = opt.Max
+		}
+		if opt.MaxAwaitTime != nil {
+			fo.MaxAwaitTime = opt.MaxAwaitTime
+		}
+		if opt.MaxTime != nil {
+			fo.MaxTime = opt.MaxTime
+		}
+		if opt.Min != nil {
+			fo.Min = opt.Min
+		}
+		if opt.NoCursorTimeout != nil {
+			fo.NoCursorTimeout = opt.NoCursorTimeout
+		}
+		if opt.OplogReplay != nil {
+			fo.OplogReplay = opt.OplogReplay
+		}
+		if opt.Projection != nil {
+			fo.Projection = opt.Projection
+		}
+		if opt.ReturnKey != nil {
+			fo.ReturnKey = opt.ReturnKey
+		}
+		if opt.ShowRecordID != nil {
+			fo.ShowRecordID = opt.ShowRecordID
+		}
+		if opt.Skip != nil {
+			fo.Skip = opt.Skip
+		}
+		if opt.Snapshot != nil {
+			fo.Snapshot = opt.Snapshot
+		}
+		if opt.Sort != nil {
+			fo.Sort = opt.Sort
+		}
+	}
+
+	return fo
+}
+
+// FindOneAndReplaceOptions represent all possible options to the findOne() function.
+type FindOneAndReplaceOptions struct {
+	BypassDocumentValidation *bool           // If true, allows the write to opt out of document-level validation.
+	Collation                *Collation      // Specifies a collation to be used
+	MaxTime                  *time.Duration  // Specifies the maximum amount of time to allow the query to run.
+	Projection               interface{}     // Limits the fields returned for all documents.
+	ReturnDocument           *ReturnDocument // Specifies whether the original or updated document should be returned.
+	Sort                     interface{}     // Specifies the order in which to return results.
+	Upsert                   *bool           // If true, creates a a new document if no document matches the query.
+}
+
+// FindOneAndReplace creates a new FindOneAndReplaceOptions instance.
+func FindOneAndReplace() *FindOneAndReplaceOptions {
+	return &FindOneAndReplaceOptions{}
+}
+
+// SetBypassDocumentValidation specifies whether or not the write should opt out of document-level validation.
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (f *FindOneAndReplaceOptions) SetBypassDocumentValidation(b bool) *FindOneAndReplaceOptions {
+	f.BypassDocumentValidation = &b
+	return f
+}
+
+// SetCollation specifies a Collation to use for the Find operation.
+func (f *FindOneAndReplaceOptions) SetCollation(collation *Collation) *FindOneAndReplaceOptions {
+	f.Collation = collation
+	return f
+}
+
+// SetMaxTime specifies the max time to allow the query to run.
+func (f *FindOneAndReplaceOptions) SetMaxTime(d time.Duration) *FindOneAndReplaceOptions {
+	f.MaxTime = &d
+	return f
+}
+
+// SetProjection adds an option to limit the fields returned for all documents.
+func (f *FindOneAndReplaceOptions) SetProjection(projection interface{}) *FindOneAndReplaceOptions {
+	f.Projection = projection
+	return f
+}
+
+// SetReturnDocument specifies whether the original or updated document should be returned.
+// If set to Before, the original document will be returned. If set to After, the updated document
+// will be returned.
+func (f *FindOneAndReplaceOptions) SetReturnDocument(rd ReturnDocument) *FindOneAndReplaceOptions {
+	f.ReturnDocument = &rd
+	return f
+}
+
+// SetSort specifies the order in which to return documents.
+func (f *FindOneAndReplaceOptions) SetSort(sort interface{}) *FindOneAndReplaceOptions {
+	f.Sort = sort
+	return f
+}
+
+// SetUpsert specifies if a new document should be created if no document matches the query.
+func (f *FindOneAndReplaceOptions) SetUpsert(b bool) *FindOneAndReplaceOptions {
+	f.Upsert = &b
+	return f
+}
+
+// MergeFindOneAndReplaceOptions combines the argued FindOneAndReplaceOptions into a single FindOneAndReplaceOptions in a last-one-wins fashion
+func MergeFindOneAndReplaceOptions(opts ...*FindOneAndReplaceOptions) *FindOneAndReplaceOptions {
+	fo := FindOneAndReplace()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.BypassDocumentValidation != nil {
+			fo.BypassDocumentValidation = opt.BypassDocumentValidation
+		}
+		if opt.Collation != nil {
+			fo.Collation = opt.Collation
+		}
+		if opt.MaxTime != nil {
+			fo.MaxTime = opt.MaxTime
+		}
+		if opt.Projection != nil {
+			fo.Projection = opt.Projection
+		}
+		if opt.ReturnDocument != nil {
+			fo.ReturnDocument = opt.ReturnDocument
+		}
+		if opt.Sort != nil {
+			fo.Sort = opt.Sort
+		}
+		if opt.Upsert != nil {
+			fo.Upsert = opt.Upsert
+		}
+	}
+
+	return fo
+}
+
+// FindOneAndUpdateOptions represent all possible options to the findOne() function.
+type FindOneAndUpdateOptions struct {
+	ArrayFilters             *ArrayFilters   // A set of filters specifying to which array elements an update should apply.
+	BypassDocumentValidation *bool           // If true, allows the write to opt out of document-level validation.
+	Collation                *Collation      // Specifies a collation to be used
+	MaxTime                  *time.Duration  // Specifies the maximum amount of time to allow the query to run.
+	Projection               interface{}     // Limits the fields returned for all documents.
+	ReturnDocument           *ReturnDocument // Specifies whether the original or updated document should be returned.
+	Sort                     interface{}     // Specifies the order in which to return results.
+	Upsert                   *bool           // If true, creates a a new document if no document matches the query.
+}
+
+// FindOneAndUpdate creates a new FindOneAndUpdateOptions instance.
+func FindOneAndUpdate() *FindOneAndUpdateOptions {
+	return &FindOneAndUpdateOptions{}
+}
+
+// SetBypassDocumentValidation sets filters that specify to which array elements an update should apply.
+func (f *FindOneAndUpdateOptions) SetBypassDocumentValidation(b bool) *FindOneAndUpdateOptions {
+	f.BypassDocumentValidation = &b
+	return f
+}
+
+// SetArrayFilters specifies a set of filters, which
+func (f *FindOneAndUpdateOptions) SetArrayFilters(filters ArrayFilters) *FindOneAndUpdateOptions {
+	f.ArrayFilters = &filters
+	return f
+}
+
+// SetCollation specifies a Collation to use for the Find operation.
+func (f *FindOneAndUpdateOptions) SetCollation(collation *Collation) *FindOneAndUpdateOptions {
+	f.Collation = collation
+	return f
+}
+
+// SetMaxTime specifies the max time to allow the query to run.
+func (f *FindOneAndUpdateOptions) SetMaxTime(d time.Duration) *FindOneAndUpdateOptions {
+	f.MaxTime = &d
+	return f
+}
+
+// SetProjection adds an option to limit the fields returned for all documents.
+func (f *FindOneAndUpdateOptions) SetProjection(projection interface{}) *FindOneAndUpdateOptions {
+	f.Projection = projection
+	return f
+}
+
+// SetReturnDocument specifies whether the original or updated document should be returned.
+// If set to Before, the original document will be returned. If set to After, the updated document
+// will be returned.
+func (f *FindOneAndUpdateOptions) SetReturnDocument(rd ReturnDocument) *FindOneAndUpdateOptions {
+	f.ReturnDocument = &rd
+	return f
+}
+
+// SetSort specifies the order in which to return documents.
+func (f *FindOneAndUpdateOptions) SetSort(sort interface{}) *FindOneAndUpdateOptions {
+	f.Sort = sort
+	return f
+}
+
+// SetUpsert specifies if a new document should be created if no document matches the query.
+func (f *FindOneAndUpdateOptions) SetUpsert(b bool) *FindOneAndUpdateOptions {
+	f.Upsert = &b
+	return f
+}
+
+// MergeFindOneAndUpdateOptions combines the argued FindOneAndUpdateOptions into a single FindOneAndUpdateOptions in a last-one-wins fashion
+func MergeFindOneAndUpdateOptions(opts ...*FindOneAndUpdateOptions) *FindOneAndUpdateOptions {
+	fo := FindOneAndUpdate()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.ArrayFilters != nil {
+			fo.ArrayFilters = opt.ArrayFilters
+		}
+		if opt.BypassDocumentValidation != nil {
+			fo.BypassDocumentValidation = opt.BypassDocumentValidation
+		}
+		if opt.Collation != nil {
+			fo.Collation = opt.Collation
+		}
+		if opt.MaxTime != nil {
+			fo.MaxTime = opt.MaxTime
+		}
+		if opt.Projection != nil {
+			fo.Projection = opt.Projection
+		}
+		if opt.ReturnDocument != nil {
+			fo.ReturnDocument = opt.ReturnDocument
+		}
+		if opt.Sort != nil {
+			fo.Sort = opt.Sort
+		}
+		if opt.Upsert != nil {
+			fo.Upsert = opt.Upsert
+		}
+	}
+
+	return fo
+}
+
+// FindOneAndDeleteOptions represent all possible options to the findOne() function.
+type FindOneAndDeleteOptions struct {
+	Collation  *Collation     // Specifies a collation to be used
+	MaxTime    *time.Duration // Specifies the maximum amount of time to allow the query to run.
+	Projection interface{}    // Limits the fields returned for all documents.
+	Sort       interface{}    // Specifies the order in which to return results.
+}
+
+// FindOneAndDelete creates a new FindOneAndDeleteOptions instance.
+func FindOneAndDelete() *FindOneAndDeleteOptions {
+	return &FindOneAndDeleteOptions{}
+}
+
+// SetCollation specifies a Collation to use for the Find operation.
+// Valid for server versions >= 3.4
+func (f *FindOneAndDeleteOptions) SetCollation(collation *Collation) *FindOneAndDeleteOptions {
+	f.Collation = collation
+	return f
+}
+
+// SetMaxTime specifies the max time to allow the query to run.
+func (f *FindOneAndDeleteOptions) SetMaxTime(d time.Duration) *FindOneAndDeleteOptions {
+	f.MaxTime = &d
+	return f
+}
+
+// SetProjection adds an option to limit the fields returned for all documents.
+func (f *FindOneAndDeleteOptions) SetProjection(projection interface{}) *FindOneAndDeleteOptions {
+	f.Projection = projection
+	return f
+}
+
+// SetSort specifies the order in which to return documents.
+func (f *FindOneAndDeleteOptions) SetSort(sort interface{}) *FindOneAndDeleteOptions {
+	f.Sort = sort
+	return f
+}
+
+// MergeFindOneAndDeleteOptions combines the argued FindOneAndDeleteOptions into a single FindOneAndDeleteOptions in a last-one-wins fashion
+func MergeFindOneAndDeleteOptions(opts ...*FindOneAndDeleteOptions) *FindOneAndDeleteOptions {
+	fo := FindOneAndDelete()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.Collation != nil {
+			fo.Collation = opt.Collation
+		}
+		if opt.MaxTime != nil {
+			fo.MaxTime = opt.MaxTime
+		}
+		if opt.Projection != nil {
+			fo.Projection = opt.Projection
+		}
+		if opt.Sort != nil {
+			fo.Sort = opt.Sort
+		}
+	}
+
+	return fo
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/gridfsoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/gridfsoptions.go
new file mode 100644
index 0000000..232a1c8
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/gridfsoptions.go
@@ -0,0 +1,268 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+	"github.com/mongodb/mongo-go-driver/x/bsonx"
+)
+
+// DefaultName is the default name for a GridFS bucket.
+var DefaultName = "fs"
+
+// DefaultChunkSize is the default size of each file chunk in bytes.
+var DefaultChunkSize int32 = 255 * 1000
+
+// DefaultRevision is the default revision number for a download by name operation.
+var DefaultRevision int32 = -1
+
+// BucketOptions represents all possible options to configure a GridFS bucket.
+type BucketOptions struct {
+	Name           *string                    // The bucket name. Defaults to "fs".
+	ChunkSizeBytes *int32                     // The chunk size in bytes. Defaults to 255KB.
+	WriteConcern   *writeconcern.WriteConcern // The write concern for the bucket. Defaults to the write concern of the database.
+	ReadConcern    *readconcern.ReadConcern   // The read concern for the bucket. Defaults to the read concern of the database.
+	ReadPreference *readpref.ReadPref         // The read preference for the bucket. Defaults to the read preference of the database.
+}
+
+// GridFSBucket creates a new *BucketOptions
+func GridFSBucket() *BucketOptions {
+	return &BucketOptions{
+		Name:           &DefaultName,
+		ChunkSizeBytes: &DefaultChunkSize,
+	}
+}
+
+// SetName sets the name for the bucket. Defaults to "fs" if not set.
+func (b *BucketOptions) SetName(name string) *BucketOptions {
+	b.Name = &name
+	return b
+}
+
+// SetChunkSizeBytes sets the chunk size in bytes for the bucket. Defaults to 255KB if not set.
+func (b *BucketOptions) SetChunkSizeBytes(i int32) *BucketOptions {
+	b.ChunkSizeBytes = &i
+	return b
+}
+
+// SetWriteConcern sets the write concern for the bucket.
+func (b *BucketOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *BucketOptions {
+	b.WriteConcern = wc
+	return b
+}
+
+// SetReadConcern sets the read concern for the bucket.
+func (b *BucketOptions) SetReadConcern(rc *readconcern.ReadConcern) *BucketOptions {
+	b.ReadConcern = rc
+	return b
+}
+
+// SetReadPreference sets the read preference for the bucket.
+func (b *BucketOptions) SetReadPreference(rp *readpref.ReadPref) *BucketOptions {
+	b.ReadPreference = rp
+	return b
+}
+
+// MergeBucketOptions combines the given *BucketOptions into a single *BucketOptions.
+// If the name or chunk size is not set in any of the given *BucketOptions, the resulting *BucketOptions will have
+// name "fs" and chunk size 255KB.
+func MergeBucketOptions(opts ...*BucketOptions) *BucketOptions {
+	b := GridFSBucket()
+
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.Name != nil {
+			b.Name = opt.Name
+		}
+		if opt.ChunkSizeBytes != nil {
+			b.ChunkSizeBytes = opt.ChunkSizeBytes
+		}
+		if opt.WriteConcern != nil {
+			b.WriteConcern = opt.WriteConcern
+		}
+		if opt.ReadConcern != nil {
+			b.ReadConcern = opt.ReadConcern
+		}
+		if opt.ReadPreference != nil {
+			b.ReadPreference = opt.ReadPreference
+		}
+	}
+
+	return b
+}
+
+// UploadOptions represents all possible options for a GridFS upload operation.
+type UploadOptions struct {
+	ChunkSizeBytes *int32    // Chunk size in bytes. Defaults to the chunk size of the bucket.
+	Metadata       bsonx.Doc // User data for the 'metadata' field of the files collection document.
+}
+
+// GridFSUpload creates a new *UploadOptions
+func GridFSUpload() *UploadOptions {
+	return &UploadOptions{}
+}
+
+// SetChunkSizeBytes sets the chunk size in bytes for the upload. Defaults to 255KB if not set.
+func (u *UploadOptions) SetChunkSizeBytes(i int32) *UploadOptions {
+	u.ChunkSizeBytes = &i
+	return u
+}
+
+// SetMetadata specfies the metadata for the upload.
+func (u *UploadOptions) SetMetadata(doc bsonx.Doc) *UploadOptions {
+	u.Metadata = doc
+	return u
+}
+
+// MergeUploadOptions combines the given *UploadOptions into a single *UploadOptions.
+// If the chunk size is not set in any of the given *UploadOptions, the resulting *UploadOptions will have chunk size
+// 255KB.
+func MergeUploadOptions(opts ...*UploadOptions) *UploadOptions {
+	u := GridFSUpload()
+
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.ChunkSizeBytes != nil {
+			u.ChunkSizeBytes = opt.ChunkSizeBytes
+		}
+		if opt.Metadata != nil {
+			u.Metadata = opt.Metadata
+		}
+	}
+
+	return u
+}
+
+// NameOptions represents all options that can be used for a GridFS download by name operation.
+type NameOptions struct {
+	Revision *int32 // Which revision (documents with the same filename and different uploadDate). Defaults to -1 (the most recent revision).
+}
+
+// GridFSName creates a new *NameOptions
+func GridFSName() *NameOptions {
+	return &NameOptions{}
+}
+
+// SetRevision specifies which revision of the file to retrieve. Defaults to -1.
+// * Revision numbers are defined as follows:
+// * 0 = the original stored file
+// * 1 = the first revision
+// * 2 = the second revision
+// * etc…
+// * -2 = the second most recent revision
+// * -1 = the most recent revision
+func (n *NameOptions) SetRevision(r int32) *NameOptions {
+	n.Revision = &r
+	return n
+}
+
+// MergeNameOptions combines the given *NameOptions into a single *NameOptions in a last one wins fashion.
+func MergeNameOptions(opts ...*NameOptions) *NameOptions {
+	n := GridFSName()
+	n.Revision = &DefaultRevision
+
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.Revision != nil {
+			n.Revision = opt.Revision
+		}
+	}
+
+	return n
+}
+
+// GridFSFindOptions represents all options for a GridFS find operation.
+type GridFSFindOptions struct {
+	BatchSize       *int32
+	Limit           *int32
+	MaxTime         *time.Duration
+	NoCursorTimeout *bool
+	Skip            *int32
+	Sort            interface{}
+}
+
+// GridFSFind creates a new GridFSFindOptions instance.
+func GridFSFind() *GridFSFindOptions {
+	return &GridFSFindOptions{}
+}
+
+// SetBatchSize sets the number of documents to return in each batch.
+func (f *GridFSFindOptions) SetBatchSize(i int32) *GridFSFindOptions {
+	f.BatchSize = &i
+	return f
+}
+
+// SetLimit specifies a limit on the number of results.
+// A negative limit implies that only 1 batch should be returned.
+func (f *GridFSFindOptions) SetLimit(i int32) *GridFSFindOptions {
+	f.Limit = &i
+	return f
+}
+
+// SetMaxTime specifies the max time to allow the query to run.
+func (f *GridFSFindOptions) SetMaxTime(d time.Duration) *GridFSFindOptions {
+	f.MaxTime = &d
+	return f
+}
+
+// SetNoCursorTimeout specifies whether or not cursors should time out after a period of inactivity.
+func (f *GridFSFindOptions) SetNoCursorTimeout(b bool) *GridFSFindOptions {
+	f.NoCursorTimeout = &b
+	return f
+}
+
+// SetSkip specifies the number of documents to skip before returning.
+func (f *GridFSFindOptions) SetSkip(i int32) *GridFSFindOptions {
+	f.Skip = &i
+	return f
+}
+
+// SetSort specifies the order in which to return documents.
+func (f *GridFSFindOptions) SetSort(sort interface{}) *GridFSFindOptions {
+	f.Sort = sort
+	return f
+}
+
+// MergeGridFSFindOptions combines the argued GridFSFindOptions into a single GridFSFindOptions in a last-one-wins fashion
+func MergeGridFSFindOptions(opts ...*GridFSFindOptions) *GridFSFindOptions {
+	fo := GridFSFind()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.BatchSize != nil {
+			fo.BatchSize = opt.BatchSize
+		}
+		if opt.Limit != nil {
+			fo.Limit = opt.Limit
+		}
+		if opt.MaxTime != nil {
+			fo.MaxTime = opt.MaxTime
+		}
+		if opt.NoCursorTimeout != nil {
+			fo.NoCursorTimeout = opt.NoCursorTimeout
+		}
+		if opt.Skip != nil {
+			fo.Skip = opt.Skip
+		}
+		if opt.Sort != nil {
+			fo.Sort = opt.Sort
+		}
+	}
+
+	return fo
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/indexoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/indexoptions.go
new file mode 100644
index 0000000..2fda698
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/indexoptions.go
@@ -0,0 +1,326 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"time"
+)
+
+// CreateIndexesOptions represents all possible options for the create() function.
+type CreateIndexesOptions struct {
+	MaxTime *time.Duration // The maximum amount of time to allow the query to run.
+}
+
+// CreateIndexes creates a new CreateIndexesOptions instance.
+func CreateIndexes() *CreateIndexesOptions {
+	return &CreateIndexesOptions{}
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the query to run.
+func (c *CreateIndexesOptions) SetMaxTime(d time.Duration) *CreateIndexesOptions {
+	c.MaxTime = &d
+	return c
+}
+
+// MergeCreateIndexesOptions combines the given *CreateIndexesOptions into a single *CreateIndexesOptions in a last one
+// wins fashion.
+func MergeCreateIndexesOptions(opts ...*CreateIndexesOptions) *CreateIndexesOptions {
+	c := CreateIndexes()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.MaxTime != nil {
+			c.MaxTime = opt.MaxTime
+		}
+	}
+
+	return c
+}
+
+// DropIndexesOptions represents all possible options for the create() function.
+type DropIndexesOptions struct {
+	MaxTime *time.Duration
+}
+
+// DropIndexes creates a new DropIndexesOptions instance.
+func DropIndexes() *DropIndexesOptions {
+	return &DropIndexesOptions{}
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the query to run.
+func (d *DropIndexesOptions) SetMaxTime(duration time.Duration) *DropIndexesOptions {
+	d.MaxTime = &duration
+	return d
+}
+
+// MergeDropIndexesOptions combines the given *DropIndexesOptions into a single *DropIndexesOptions in a last one
+// wins fashion.
+func MergeDropIndexesOptions(opts ...*DropIndexesOptions) *DropIndexesOptions {
+	c := DropIndexes()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.MaxTime != nil {
+			c.MaxTime = opt.MaxTime
+		}
+	}
+
+	return c
+}
+
+// ListIndexesOptions represents all possible options for the create() function.
+type ListIndexesOptions struct {
+	BatchSize *int32
+	MaxTime   *time.Duration
+}
+
+// ListIndexes creates a new ListIndexesOptions instance.
+func ListIndexes() *ListIndexesOptions {
+	return &ListIndexesOptions{}
+}
+
+// SetBatchSize specifies the number of documents to return in every batch.
+func (l *ListIndexesOptions) SetBatchSize(i int32) *ListIndexesOptions {
+	l.BatchSize = &i
+	return l
+}
+
+// SetMaxTime specifies the maximum amount of time to allow the query to run.
+func (l *ListIndexesOptions) SetMaxTime(d time.Duration) *ListIndexesOptions {
+	l.MaxTime = &d
+	return l
+}
+
+// MergeListIndexesOptions combines the given *ListIndexesOptions into a single *ListIndexesOptions in a last one
+// wins fashion.
+func MergeListIndexesOptions(opts ...*ListIndexesOptions) *ListIndexesOptions {
+	c := ListIndexes()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.MaxTime != nil {
+			c.MaxTime = opt.MaxTime
+		}
+	}
+
+	return c
+}
+
+// IndexOptions represents all possible options to configure a new index.
+type IndexOptions struct {
+	Background              *bool
+	ExpireAfterSeconds      *int32
+	Name                    *string
+	Sparse                  *bool
+	StorageEngine           interface{}
+	Unique                  *bool
+	Version                 *int32
+	DefaultLanguage         *string
+	LanguageOverride        *string
+	TextVersion             *int32
+	Weights                 interface{}
+	SphereVersion           *int32
+	Bits                    *int32
+	Max                     *float64
+	Min                     *float64
+	BucketSize              *int32
+	PartialFilterExpression interface{}
+	Collation               *Collation
+}
+
+// Index creates a new *IndexOptions
+func Index() *IndexOptions {
+	return &IndexOptions{}
+}
+
+// SetBackground sets the background option. If true, the server will create the index in the background and not block
+// other tasks
+func (i *IndexOptions) SetBackground(background bool) *IndexOptions {
+	i.Background = &background
+	return i
+}
+
+// SetExpireAfterSeconds specifies the number of seconds for a document to remain in a collection.
+func (i *IndexOptions) SetExpireAfterSeconds(seconds int32) *IndexOptions {
+	i.ExpireAfterSeconds = &seconds
+	return i
+}
+
+// SetName specifies a name for the index.
+// If not set, a name will be generated in the format "[field]_[direction]".
+// If multiple indexes are created for the same key pattern with different collations, a name must be provided to avoid
+// ambiguity.
+func (i *IndexOptions) SetName(name string) *IndexOptions {
+	i.Name = &name
+	return i
+}
+
+// SetSparse sets the sparse option.
+// If true, the index will only reference documents with the specified field in the index.
+func (i *IndexOptions) SetSparse(sparse bool) *IndexOptions {
+	i.Sparse = &sparse
+	return i
+}
+
+// SetStorageEngine specifies the storage engine to use.
+// Valid for server versions >= 3.0
+func (i *IndexOptions) SetStorageEngine(engine interface{}) *IndexOptions {
+	i.StorageEngine = engine
+	return i
+}
+
+// SetUnique forces the index to be unique.
+func (i *IndexOptions) SetUnique(unique bool) *IndexOptions {
+	i.Unique = &unique
+	return i
+}
+
+// SetVersion specifies the index version number, either 0 or 1.
+func (i *IndexOptions) SetVersion(version int32) *IndexOptions {
+	i.Version = &version
+	return i
+}
+
+// SetDefaultLanguage specifies the default language for text indexes.
+// If not set, this will default to english.
+func (i *IndexOptions) SetDefaultLanguage(language string) *IndexOptions {
+	i.DefaultLanguage = &language
+	return i
+}
+
+// SetLanguageOverride specifies the field in the document to override the language.
+func (i *IndexOptions) SetLanguageOverride(override string) *IndexOptions {
+	i.LanguageOverride = &override
+	return i
+}
+
+// SetTextVersion specifies the text index version number.
+// MongoDB version 2.4 can only support version 1.
+// MongoDB versions 2.6 and higher can support versions 1 or 2.
+func (i *IndexOptions) SetTextVersion(version int32) *IndexOptions {
+	i.TextVersion = &version
+	return i
+}
+
+// SetWeights specifies fields in the index and their corresponding weight values.
+func (i *IndexOptions) SetWeights(weights interface{}) *IndexOptions {
+	i.Weights = weights
+	return i
+}
+
+// SetSphereVersion specifies the 2dsphere index version number.
+// MongoDB version 2.4 can only support version 1.
+// MongoDB versions 2.6 and higher can support versions 1 or 2.
+func (i *IndexOptions) SetSphereVersion(version int32) *IndexOptions {
+	i.SphereVersion = &version
+	return i
+}
+
+// SetBits specifies the precision of the stored geo hash in the 2d index, from 1 to 32.
+func (i *IndexOptions) SetBits(bits int32) *IndexOptions {
+	i.Bits = &bits
+	return i
+}
+
+// SetMax specifies the maximum boundary for latitude and longitude in the 2d index.
+func (i *IndexOptions) SetMax(max float64) *IndexOptions {
+	i.Max = &max
+	return i
+}
+
+// SetMin specifies the minimum boundary for latitude and longitude in the 2d index.
+func (i *IndexOptions) SetMin(min float64) *IndexOptions {
+	i.Min = &min
+	return i
+}
+
+// SetBucketSize specifies number of units within which to group the location values in a geo haystack index.
+func (i *IndexOptions) SetBucketSize(bucketSize int32) *IndexOptions {
+	i.BucketSize = &bucketSize
+	return i
+}
+
+// SetPartialFilterExpression specifies a filter for use in a partial index. Only documents that match the filter
+// expression are included in the index.
+func (i *IndexOptions) SetPartialFilterExpression(expression interface{}) *IndexOptions {
+	i.PartialFilterExpression = expression
+	return i
+}
+
+// SetCollation specifies a Collation to use for the operation.
+// Valid for server versions >= 3.4
+func (i *IndexOptions) SetCollation(collation *Collation) *IndexOptions {
+	i.Collation = collation
+	return i
+}
+
+// MergeIndexOptions combines the given *IndexOptions into a single *IndexOptions in a last one wins fashion.
+func MergeIndexOptions(opts ...*IndexOptions) *IndexOptions {
+	i := Index()
+
+	for _, opt := range opts {
+		if opt.Background != nil {
+			i.Background = opt.Background
+		}
+		if opt.ExpireAfterSeconds != nil {
+			i.ExpireAfterSeconds = opt.ExpireAfterSeconds
+		}
+		if opt.Name != nil {
+			i.Name = opt.Name
+		}
+		if opt.Sparse != nil {
+			i.Sparse = opt.Sparse
+		}
+		if opt.StorageEngine != nil {
+			i.StorageEngine = opt.StorageEngine
+		}
+		if opt.Unique != nil {
+			i.Unique = opt.Unique
+		}
+		if opt.Version != nil {
+			i.Version = opt.Version
+		}
+		if opt.DefaultLanguage != nil {
+			i.DefaultLanguage = opt.DefaultLanguage
+		}
+		if opt.LanguageOverride != nil {
+			i.LanguageOverride = opt.LanguageOverride
+		}
+		if opt.TextVersion != nil {
+			i.TextVersion = opt.TextVersion
+		}
+		if opt.Weights != nil {
+			i.Weights = opt.Weights
+		}
+		if opt.SphereVersion != nil {
+			i.SphereVersion = opt.SphereVersion
+		}
+		if opt.Bits != nil {
+			i.Bits = opt.Bits
+		}
+		if opt.Max != nil {
+			i.Max = opt.Max
+		}
+		if opt.Min != nil {
+			i.Min = opt.Min
+		}
+		if opt.BucketSize != nil {
+			i.BucketSize = opt.BucketSize
+		}
+		if opt.PartialFilterExpression != nil {
+			i.PartialFilterExpression = opt.PartialFilterExpression
+		}
+		if opt.Collation != nil {
+			i.Collation = opt.Collation
+		}
+	}
+
+	return i
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/insertoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/insertoptions.go
new file mode 100644
index 0000000..064ede3
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/insertoptions.go
@@ -0,0 +1,84 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// InsertOneOptions represents all possible options to the insertOne()
+type InsertOneOptions struct {
+	BypassDocumentValidation *bool // If true, allows the write to opt-out of document level validation
+}
+
+// InsertOne returns a pointer to a new InsertOneOptions
+func InsertOne() *InsertOneOptions {
+	return &InsertOneOptions{}
+}
+
+// SetBypassDocumentValidation allows the write to opt-out of document level validation.
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (ioo *InsertOneOptions) SetBypassDocumentValidation(b bool) *InsertOneOptions {
+	ioo.BypassDocumentValidation = &b
+	return ioo
+}
+
+// MergeInsertOneOptions combines the argued InsertOneOptions into a single InsertOneOptions in a last-one-wins fashion
+func MergeInsertOneOptions(opts ...*InsertOneOptions) *InsertOneOptions {
+	ioOpts := InsertOne()
+	for _, ioo := range opts {
+		if ioo == nil {
+			continue
+		}
+		if ioo.BypassDocumentValidation != nil {
+			ioOpts.BypassDocumentValidation = ioo.BypassDocumentValidation
+		}
+	}
+
+	return ioOpts
+}
+
+// InsertManyOptions represents all possible options to the insertMany()
+type InsertManyOptions struct {
+	BypassDocumentValidation *bool // If true, allows the write to opt-out of document level validation
+	Ordered                  *bool // If true, when an insert fails, return without performing the remaining inserts. Defaults to true.
+}
+
+// InsertMany returns a pointer to a new InsertManyOptions
+func InsertMany() *InsertManyOptions {
+	return &InsertManyOptions{
+		Ordered: &DefaultOrdered,
+	}
+}
+
+// SetBypassDocumentValidation allows the write to opt-out of document level validation.
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (imo *InsertManyOptions) SetBypassDocumentValidation(b bool) *InsertManyOptions {
+	imo.BypassDocumentValidation = &b
+	return imo
+}
+
+// SetOrdered configures the ordered option. If true, when a write fails, the function will return without attempting
+// remaining writes. Defaults to true.
+func (imo *InsertManyOptions) SetOrdered(b bool) *InsertManyOptions {
+	imo.Ordered = &b
+	return imo
+}
+
+// MergeInsertManyOptions combines the argued InsertManyOptions into a single InsertManyOptions in a last-one-wins fashion
+func MergeInsertManyOptions(opts ...*InsertManyOptions) *InsertManyOptions {
+	imOpts := InsertMany()
+	for _, imo := range opts {
+		if imo == nil {
+			continue
+		}
+		if imo.BypassDocumentValidation != nil {
+			imOpts.BypassDocumentValidation = imo.BypassDocumentValidation
+		}
+		if imo.Ordered != nil {
+			imOpts.Ordered = imo.Ordered
+		}
+	}
+
+	return imOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/listcollectionsoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/listcollectionsoptions.go
new file mode 100644
index 0000000..e44ad4a
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/listcollectionsoptions.go
@@ -0,0 +1,39 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// ListCollectionsOptions represents all possible options for a listCollections command.
+type ListCollectionsOptions struct {
+	NameOnly *bool // If true, only the collection names will be returned.
+}
+
+// ListCollections creates a new *ListCollectionsOptions
+func ListCollections() *ListCollectionsOptions {
+	return &ListCollectionsOptions{}
+}
+
+// SetNameOnly specifies whether to return only the collection names.
+func (lc *ListCollectionsOptions) SetNameOnly(b bool) *ListCollectionsOptions {
+	lc.NameOnly = &b
+	return lc
+}
+
+// MergeListCollectionsOptions combines the given *ListCollectionsOptions into a single *ListCollectionsOptions in a
+// last one wins fashion.
+func MergeListCollectionsOptions(opts ...*ListCollectionsOptions) *ListCollectionsOptions {
+	lc := ListCollections()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.NameOnly != nil {
+			lc.NameOnly = opt.NameOnly
+		}
+	}
+
+	return lc
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/listdatabasesoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/listdatabasesoptions.go
new file mode 100644
index 0000000..5efb6e8
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/listdatabasesoptions.go
@@ -0,0 +1,39 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// ListDatabasesOptions represents all possible options for a listDatabases command.
+type ListDatabasesOptions struct {
+	NameOnly *bool // If true, only the database names will be returned.
+}
+
+// ListDatabases creates a new *ListDatabasesOptions
+func ListDatabases() *ListDatabasesOptions {
+	return &ListDatabasesOptions{}
+}
+
+// SetNameOnly specifies whether to return only the database names.
+func (ld *ListDatabasesOptions) SetNameOnly(b bool) *ListDatabasesOptions {
+	ld.NameOnly = &b
+	return ld
+}
+
+// MergeListDatabasesOptions combines the given *ListDatabasesOptions into a single *ListDatabasesOptions in a last one
+// wins fashion.
+func MergeListDatabasesOptions(opts ...*ListDatabasesOptions) *ListDatabasesOptions {
+	ld := ListDatabases()
+	for _, opt := range opts {
+		if opts == nil {
+			continue
+		}
+		if opt.NameOnly != nil {
+			ld.NameOnly = opt.NameOnly
+		}
+	}
+
+	return ld
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/mongooptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/mongooptions.go
new file mode 100644
index 0000000..22f383b
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/mongooptions.go
@@ -0,0 +1,163 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+	"github.com/mongodb/mongo-go-driver/x/bsonx"
+)
+
+// Collation allows users to specify language-specific rules for string comparison, such as
+// rules for lettercase and accent marks.
+type Collation struct {
+	Locale          string `bson:",omitempty"` // The locale
+	CaseLevel       bool   `bson:",omitempty"` // The case level
+	CaseFirst       string `bson:",omitempty"` // The case ordering
+	Strength        int    `bson:",omitempty"` // The number of comparision levels to use
+	NumericOrdering bool   `bson:",omitempty"` // Whether to order numbers based on numerical order and not collation order
+	Alternate       string `bson:",omitempty"` // Whether spaces and punctuation are considered base characters
+	MaxVariable     string `bson:",omitempty"` // Which characters are affected by alternate: "shifted"
+	Normalization   bool   `bson:",omitempty"` // Causes text to be normalized into Unicode NFD
+	Backwards       bool   `bson:",omitempty"` // Causes secondary differences to be considered in reverse order, as it is done in the French language
+}
+
+// ToDocument converts the Collation to a *bsonx.Document
+func (co *Collation) ToDocument() bsonx.Doc {
+	doc := bsonx.Doc{}
+	if co.Locale != "" {
+		doc = append(doc, bsonx.Elem{"locale", bsonx.String(co.Locale)})
+	}
+	if co.CaseLevel {
+		doc = append(doc, bsonx.Elem{"caseLevel", bsonx.Boolean(true)})
+	}
+	if co.CaseFirst != "" {
+		doc = append(doc, bsonx.Elem{"caseFirst", bsonx.String(co.CaseFirst)})
+	}
+	if co.Strength != 0 {
+		doc = append(doc, bsonx.Elem{"strength", bsonx.Int32(int32(co.Strength))})
+	}
+	if co.NumericOrdering {
+		doc = append(doc, bsonx.Elem{"numericOrdering", bsonx.Boolean(true)})
+	}
+	if co.Alternate != "" {
+		doc = append(doc, bsonx.Elem{"alternate", bsonx.String(co.Alternate)})
+	}
+	if co.MaxVariable != "" {
+		doc = append(doc, bsonx.Elem{"maxVariable", bsonx.String(co.MaxVariable)})
+	}
+	if co.Normalization {
+		doc = append(doc, bsonx.Elem{"normalization", bsonx.Boolean(co.Normalization)})
+	}
+	if co.Backwards {
+		doc = append(doc, bsonx.Elem{"backwards", bsonx.Boolean(true)})
+	}
+	return doc
+}
+
+// CursorType specifies whether a cursor should close when the last data is retrieved. See
+// NonTailable, Tailable, and TailableAwait.
+type CursorType int8
+
+const (
+	// NonTailable specifies that a cursor should close after retrieving the last data.
+	NonTailable CursorType = iota
+	// Tailable specifies that a cursor should not close when the last data is retrieved and can be resumed later.
+	Tailable
+	// TailableAwait specifies that a cursor should not close when the last data is retrieved and
+	// that it should block for a certain amount of time for new data before returning no data.
+	TailableAwait
+)
+
+// ReturnDocument specifies whether a findAndUpdate operation should return the document as it was
+// before the update or as it is after the update.
+type ReturnDocument int8
+
+const (
+	// Before specifies that findAndUpdate should return the document as it was before the update.
+	Before ReturnDocument = iota
+	// After specifies that findAndUpdate should return the document as it is after the update.
+	After
+)
+
+// FullDocument specifies whether a change stream should include a copy of the entire document that was changed from
+// some time after the change occurred.
+type FullDocument string
+
+const (
+	// Default does not include a document copy
+	Default FullDocument = "default"
+	// UpdateLookup includes a delta describing the changes to the document and a copy of the entire document that
+	// was changed
+	UpdateLookup FullDocument = "updateLookup"
+)
+
+// ArrayFilters is used to hold filters for the array filters CRUD option. If a registry is nil, bson.DefaultRegistry
+// will be used when converting the filter interfaces to BSON.
+type ArrayFilters struct {
+	Registry *bsoncodec.Registry // The registry to use for converting filters. Defaults to bson.DefaultRegistry.
+	Filters  []interface{}       // The filters to apply
+}
+
+// ToArray builds a bsonx.Arr from the provided ArrayFilters.
+func (af *ArrayFilters) ToArray() (bsonx.Arr, error) {
+	docs := make([]bsonx.Doc, 0, len(af.Filters))
+	for _, f := range af.Filters {
+		d, err := transformDocument(af.Registry, f)
+		if err != nil {
+			return nil, err
+		}
+		docs = append(docs, d)
+	}
+
+	arr := bsonx.Arr{}
+	for _, doc := range docs {
+		arr = append(arr, bsonx.Document(doc))
+	}
+
+	return arr, nil
+}
+
+// MarshalError is returned when attempting to transform a value into a document
+// results in an error.
+type MarshalError struct {
+	Value interface{}
+	Err   error
+}
+
+// Error implements the error interface.
+func (me MarshalError) Error() string {
+	return fmt.Sprintf("cannot transform type %s to a *bsonx.Document", reflect.TypeOf(me.Value))
+}
+
+var defaultRegistry = bson.DefaultRegistry
+
+func transformDocument(registry *bsoncodec.Registry, val interface{}) (bsonx.Doc, error) {
+	if val == nil {
+		return bsonx.Doc{}, nil
+	}
+	reg := defaultRegistry
+	if registry != nil {
+		reg = registry
+	}
+
+	if bs, ok := val.([]byte); ok {
+		// Slight optimization so we'll just use MarshalBSON and not go through the codec machinery.
+		val = bson.Raw(bs)
+	}
+
+	// TODO(skriptble): Use a pool of these instead.
+	buf := make([]byte, 0, 256)
+	b, err := bson.MarshalAppendWithRegistry(reg, buf, val)
+	if err != nil {
+		return nil, MarshalError{Value: val, Err: err}
+	}
+	return bsonx.ReadDoc(b)
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/replaceoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/replaceoptions.go
new file mode 100644
index 0000000..7a8c2ba
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/replaceoptions.go
@@ -0,0 +1,60 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// ReplaceOptions represents all possible options to the replaceOne() function
+type ReplaceOptions struct {
+	BypassDocumentValidation *bool      // If true, allows the write to opt-out of document level validation
+	Collation                *Collation // Specifies a collation
+	Upsert                   *bool      // When true, creates a new document if no document matches the query
+}
+
+// Replace returns a pointer to a new ReplaceOptions
+func Replace() *ReplaceOptions {
+	return &ReplaceOptions{}
+}
+
+// SetBypassDocumentValidation allows the write to opt-out of document level validation.
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (ro *ReplaceOptions) SetBypassDocumentValidation(b bool) *ReplaceOptions {
+	ro.BypassDocumentValidation = &b
+	return ro
+}
+
+// SetCollation specifies a collation.
+// Valid for servers >= 3.4
+func (ro *ReplaceOptions) SetCollation(c *Collation) *ReplaceOptions {
+	ro.Collation = c
+	return ro
+}
+
+// SetUpsert allows the creation of a new document if not document matches the query
+func (ro *ReplaceOptions) SetUpsert(b bool) *ReplaceOptions {
+	ro.Upsert = &b
+	return ro
+}
+
+// MergeReplaceOptions combines the argued ReplaceOptions into a single ReplaceOptions in a last-one-wins fashion
+func MergeReplaceOptions(opts ...*ReplaceOptions) *ReplaceOptions {
+	rOpts := Replace()
+	for _, ro := range opts {
+		if ro == nil {
+			continue
+		}
+		if ro.BypassDocumentValidation != nil {
+			rOpts.BypassDocumentValidation = ro.BypassDocumentValidation
+		}
+		if ro.Collation != nil {
+			rOpts.Collation = ro.Collation
+		}
+		if ro.Upsert != nil {
+			rOpts.Upsert = ro.Upsert
+		}
+	}
+
+	return rOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/runcmdoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/runcmdoptions.go
new file mode 100644
index 0000000..c7c696d
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/runcmdoptions.go
@@ -0,0 +1,40 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import "github.com/mongodb/mongo-go-driver/mongo/readpref"
+
+// RunCmdOptions represents all possible options for a runCommand operation.
+type RunCmdOptions struct {
+	ReadPreference *readpref.ReadPref // The read preference for the operation.
+}
+
+// RunCmd creates a new *RunCmdOptions
+func RunCmd() *RunCmdOptions {
+	return &RunCmdOptions{}
+}
+
+// SetReadPreference sets the read preference for the operation.
+func (rc *RunCmdOptions) SetReadPreference(rp *readpref.ReadPref) *RunCmdOptions {
+	rc.ReadPreference = rp
+	return rc
+}
+
+// MergeRunCmdOptions combines the given *RunCmdOptions into one *RunCmdOptions in a last one wins fashion.
+func MergeRunCmdOptions(opts ...*RunCmdOptions) *RunCmdOptions {
+	rc := RunCmd()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.ReadPreference != nil {
+			rc.ReadPreference = opt.ReadPreference
+		}
+	}
+
+	return rc
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/sessionoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/sessionoptions.go
new file mode 100644
index 0000000..ffe45e6
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/sessionoptions.go
@@ -0,0 +1,79 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+)
+
+// DefaultCausalConsistency is the default value for the CausalConsistency option.
+var DefaultCausalConsistency = true
+
+// SessionOptions represents all possible options for creating a new session.
+type SessionOptions struct {
+	CausalConsistency     *bool                      // Specifies if reads should be causally consistent. Defaults to true.
+	DefaultReadConcern    *readconcern.ReadConcern   // The default read concern for transactions started in the session.
+	DefaultReadPreference *readpref.ReadPref         // The default read preference for transactions started in the session.
+	DefaultWriteConcern   *writeconcern.WriteConcern // The default write concern for transactions started in the session.
+}
+
+// Session creates a new *SessionOptions
+func Session() *SessionOptions {
+	return &SessionOptions{
+		CausalConsistency: &DefaultCausalConsistency,
+	}
+}
+
+// SetCausalConsistency specifies if a session should be causally consistent. Defaults to true.
+func (s *SessionOptions) SetCausalConsistency(b bool) *SessionOptions {
+	s.CausalConsistency = &b
+	return s
+}
+
+// SetDefaultReadConcern sets the default read concern for transactions started in a session.
+func (s *SessionOptions) SetDefaultReadConcern(rc *readconcern.ReadConcern) *SessionOptions {
+	s.DefaultReadConcern = rc
+	return s
+}
+
+// SetDefaultReadPreference sets the default read preference for transactions started in a session.
+func (s *SessionOptions) SetDefaultReadPreference(rp *readpref.ReadPref) *SessionOptions {
+	s.DefaultReadPreference = rp
+	return s
+}
+
+// SetDefaultWriteConcern sets the default write concern for transactions started in a session.
+func (s *SessionOptions) SetDefaultWriteConcern(wc *writeconcern.WriteConcern) *SessionOptions {
+	s.DefaultWriteConcern = wc
+	return s
+}
+
+// MergeSessionOptions combines the given *SessionOptions into a single *SessionOptions in a last one wins fashion.
+func MergeSessionOptions(opts ...*SessionOptions) *SessionOptions {
+	s := Session()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.CausalConsistency != nil {
+			s.CausalConsistency = opt.CausalConsistency
+		}
+		if opt.DefaultReadConcern != nil {
+			s.DefaultReadConcern = opt.DefaultReadConcern
+		}
+		if opt.DefaultReadPreference != nil {
+			s.DefaultReadPreference = opt.DefaultReadPreference
+		}
+		if opt.DefaultWriteConcern != nil {
+			s.DefaultWriteConcern = opt.DefaultWriteConcern
+		}
+	}
+
+	return s
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/transactionoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/transactionoptions.go
new file mode 100644
index 0000000..5aec1b9
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/transactionoptions.go
@@ -0,0 +1,65 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+import (
+	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
+	"github.com/mongodb/mongo-go-driver/mongo/readpref"
+	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
+)
+
+// TransactionOptions represents all possible options for starting a transaction.
+type TransactionOptions struct {
+	ReadConcern    *readconcern.ReadConcern   // The read concern for the transaction. Defaults to the session's read concern.
+	ReadPreference *readpref.ReadPref         // The read preference for the transaction. Defaults to the session's read preference.
+	WriteConcern   *writeconcern.WriteConcern // The write concern for the transaction. Defaults to the session's write concern.
+}
+
+// Transaction creates a new *TransactionOptions
+func Transaction() *TransactionOptions {
+	return &TransactionOptions{}
+}
+
+// SetReadConcern sets the read concern for the transaction.
+func (t *TransactionOptions) SetReadConcern(rc *readconcern.ReadConcern) *TransactionOptions {
+	t.ReadConcern = rc
+	return t
+}
+
+// SetReadPreference sets the read preference for the transaction.
+func (t *TransactionOptions) SetReadPreference(rp *readpref.ReadPref) *TransactionOptions {
+	t.ReadPreference = rp
+	return t
+}
+
+// SetWriteConcern sets the write concern for the transaction.
+func (t *TransactionOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *TransactionOptions {
+	t.WriteConcern = wc
+	return t
+}
+
+// MergeTransactionOptions combines the given *TransactionOptions into a single *TransactionOptions in a last one wins
+// fashion.
+func MergeTransactionOptions(opts ...*TransactionOptions) *TransactionOptions {
+	t := Transaction()
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		if opt.ReadConcern != nil {
+			t.ReadConcern = opt.ReadConcern
+		}
+		if opt.ReadPreference != nil {
+			t.ReadPreference = opt.ReadPreference
+		}
+		if opt.WriteConcern != nil {
+			t.WriteConcern = opt.WriteConcern
+		}
+	}
+
+	return t
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/options/updateoptions.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/updateoptions.go
new file mode 100644
index 0000000..468ccda
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/options/updateoptions.go
@@ -0,0 +1,71 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package options
+
+// UpdateOptions represents all possible options to the updateOne() and updateMany() functions
+type UpdateOptions struct {
+	ArrayFilters             *ArrayFilters // A set of filters specifying to which array elements an update should apply
+	BypassDocumentValidation *bool         // If true, allows the write to opt-out of document level validation
+	Collation                *Collation    // Specifies a collation
+	Upsert                   *bool         // When true, creates a new document if no document matches the query
+}
+
+// Update returns a pointer to a new UpdateOptions
+func Update() *UpdateOptions {
+	return &UpdateOptions{}
+}
+
+// SetArrayFilters specifies a set of filters specifying to which array elements an update should apply
+// Valid for server versions >= 3.6.
+func (uo *UpdateOptions) SetArrayFilters(af ArrayFilters) *UpdateOptions {
+	uo.ArrayFilters = &af
+	return uo
+}
+
+// SetBypassDocumentValidation allows the write to opt-out of document level validation.
+// Valid for server versions >= 3.2. For servers < 3.2, this option is ignored.
+func (uo *UpdateOptions) SetBypassDocumentValidation(b bool) *UpdateOptions {
+	uo.BypassDocumentValidation = &b
+	return uo
+}
+
+// SetCollation specifies a collation.
+// Valid for server versions >= 3.4.
+func (uo *UpdateOptions) SetCollation(c *Collation) *UpdateOptions {
+	uo.Collation = c
+	return uo
+}
+
+// SetUpsert allows the creation of a new document if not document matches the query
+func (uo *UpdateOptions) SetUpsert(b bool) *UpdateOptions {
+	uo.Upsert = &b
+	return uo
+}
+
+// MergeUpdateOptions combines the argued UpdateOptions into a single UpdateOptions in a last-one-wins fashion
+func MergeUpdateOptions(opts ...*UpdateOptions) *UpdateOptions {
+	uOpts := Update()
+	for _, uo := range opts {
+		if uo == nil {
+			continue
+		}
+		if uo.ArrayFilters != nil {
+			uOpts.ArrayFilters = uo.ArrayFilters
+		}
+		if uo.BypassDocumentValidation != nil {
+			uOpts.BypassDocumentValidation = uo.BypassDocumentValidation
+		}
+		if uo.Collation != nil {
+			uOpts.Collation = uo.Collation
+		}
+		if uo.Upsert != nil {
+			uOpts.Upsert = uo.Upsert
+		}
+	}
+
+	return uOpts
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/readconcern/readconcern.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/readconcern/readconcern.go
new file mode 100644
index 0000000..c185fff
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/readconcern/readconcern.go
@@ -0,0 +1,77 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package readconcern
+
+import (
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+	"github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
+)
+
+// ReadConcern for replica sets and replica set shards determines which data to return from a query.
+type ReadConcern struct {
+	level string
+}
+
+// Option is an option to provide when creating a ReadConcern.
+type Option func(concern *ReadConcern)
+
+// Level creates an option that sets the level of a ReadConcern.
+func Level(level string) Option {
+	return func(concern *ReadConcern) {
+		concern.level = level
+	}
+}
+
+// Local specifies that the query should return the instance’s most recent data.
+func Local() *ReadConcern {
+	return New(Level("local"))
+}
+
+// Majority specifies that the query should return the instance’s most recent data acknowledged as
+// having been written to a majority of members in the replica set.
+func Majority() *ReadConcern {
+	return New(Level("majority"))
+}
+
+// Linearizable specifies that the query should return data that reflects all successful writes
+// issued with a write concern of "majority" and acknowledged prior to the start of the read operation.
+func Linearizable() *ReadConcern {
+	return New(Level("linearizable"))
+}
+
+// Available specifies that the query should return data from the instance with no guarantee
+// that the data has been written to a majority of the replica set members (i.e. may be rolled back).
+func Available() *ReadConcern {
+	return New(Level("available"))
+}
+
+// Snapshot is only available for operations within multi-document transactions.
+func Snapshot() *ReadConcern {
+	return New(Level("snapshot"))
+}
+
+// New constructs a new read concern from the given string.
+func New(options ...Option) *ReadConcern {
+	concern := &ReadConcern{}
+
+	for _, option := range options {
+		option(concern)
+	}
+
+	return concern
+}
+
+// MarshalBSONValue implements the bson.ValueMarshaler interface.
+func (rc *ReadConcern) MarshalBSONValue() (bsontype.Type, []byte, error) {
+	var elems []byte
+
+	if len(rc.level) > 0 {
+		elems = bsoncore.AppendStringElement(elems, "level", rc.level)
+	}
+
+	return bsontype.EmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/mode.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/mode.go
new file mode 100644
index 0000000..e7030c6
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/mode.go
@@ -0,0 +1,56 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package readpref
+
+import (
+	"fmt"
+	"strings"
+)
+
+// Mode indicates the user's preference on reads.
+type Mode uint8
+
+// Mode constants
+const (
+	_ Mode = iota
+	// PrimaryMode indicates that only a primary is
+	// considered for reading. This is the default
+	// mode.
+	PrimaryMode
+	// PrimaryPreferredMode indicates that if a primary
+	// is available, use it; otherwise, eligible
+	// secondaries will be considered.
+	PrimaryPreferredMode
+	// SecondaryMode indicates that only secondaries
+	// should be considered.
+	SecondaryMode
+	// SecondaryPreferredMode indicates that only secondaries
+	// should be considered when one is available. If none
+	// are available, then a primary will be considered.
+	SecondaryPreferredMode
+	// NearestMode indicates that all primaries and secondaries
+	// will be considered.
+	NearestMode
+)
+
+// ModeFromString returns a mode corresponding to
+// mode.
+func ModeFromString(mode string) (Mode, error) {
+	switch strings.ToLower(mode) {
+	case "primary":
+		return PrimaryMode, nil
+	case "primarypreferred":
+		return PrimaryPreferredMode, nil
+	case "secondary":
+		return SecondaryMode, nil
+	case "secondarypreferred":
+		return SecondaryPreferredMode, nil
+	case "nearest":
+		return NearestMode, nil
+	}
+	return Mode(0), fmt.Errorf("unknown read preference %v", mode)
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/options.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/options.go
new file mode 100644
index 0000000..a81cf3e
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/options.go
@@ -0,0 +1,60 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package readpref
+
+import (
+	"errors"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/tag"
+)
+
+// ErrInvalidTagSet indicates that an invalid set of tags was specified.
+var ErrInvalidTagSet = errors.New("an even number of tags must be specified")
+
+// Option configures a read preference
+type Option func(*ReadPref) error
+
+// WithMaxStaleness sets the maximum staleness a
+// server is allowed.
+func WithMaxStaleness(ms time.Duration) Option {
+	return func(rp *ReadPref) error {
+		rp.maxStaleness = ms
+		rp.maxStalenessSet = true
+		return nil
+	}
+}
+
+// WithTags sets a single tag set used to match
+// a server. The last call to WithTags or WithTagSets
+// overrides all previous calls to either method.
+func WithTags(tags ...string) Option {
+	return func(rp *ReadPref) error {
+		length := len(tags)
+		if length < 2 || length%2 != 0 {
+			return ErrInvalidTagSet
+		}
+
+		tagset := make(tag.Set, 0, length/2)
+
+		for i := 1; i < length; i += 2 {
+			tagset = append(tagset, tag.Tag{Name: tags[i-1], Value: tags[i]})
+		}
+
+		return WithTagSets(tagset)(rp)
+	}
+}
+
+// WithTagSets sets the tag sets used to match
+// a server. The last call to WithTags or WithTagSets
+// overrides all previous calls to either method.
+func WithTagSets(tagSets ...tag.Set) Option {
+	return func(rp *ReadPref) error {
+		rp.tagSets = tagSets
+		return nil
+	}
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/readpref.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/readpref.go
new file mode 100644
index 0000000..0d624ff
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/readpref/readpref.go
@@ -0,0 +1,99 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package readpref
+
+import (
+	"errors"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/tag"
+)
+
+var (
+	errInvalidReadPreference = errors.New("can not specify tags or max staleness on primary")
+)
+
+var primary = ReadPref{mode: PrimaryMode}
+
+// Primary constructs a read preference with a PrimaryMode.
+func Primary() *ReadPref {
+	return &primary
+}
+
+// PrimaryPreferred constructs a read preference with a PrimaryPreferredMode.
+func PrimaryPreferred(opts ...Option) *ReadPref {
+	// New only returns an error with a mode of Primary
+	rp, _ := New(PrimaryPreferredMode, opts...)
+	return rp
+}
+
+// SecondaryPreferred constructs a read preference with a SecondaryPreferredMode.
+func SecondaryPreferred(opts ...Option) *ReadPref {
+	// New only returns an error with a mode of Primary
+	rp, _ := New(SecondaryPreferredMode, opts...)
+	return rp
+}
+
+// Secondary constructs a read preference with a SecondaryMode.
+func Secondary(opts ...Option) *ReadPref {
+	// New only returns an error with a mode of Primary
+	rp, _ := New(SecondaryMode, opts...)
+	return rp
+}
+
+// Nearest constructs a read preference with a NearestMode.
+func Nearest(opts ...Option) *ReadPref {
+	// New only returns an error with a mode of Primary
+	rp, _ := New(NearestMode, opts...)
+	return rp
+}
+
+// New creates a new ReadPref.
+func New(mode Mode, opts ...Option) (*ReadPref, error) {
+	rp := &ReadPref{
+		mode: mode,
+	}
+
+	if mode == PrimaryMode && len(opts) != 0 {
+		return nil, errInvalidReadPreference
+	}
+
+	for _, opt := range opts {
+		err := opt(rp)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return rp, nil
+}
+
+// ReadPref determines which servers are considered suitable for read operations.
+type ReadPref struct {
+	maxStaleness    time.Duration
+	maxStalenessSet bool
+	mode            Mode
+	tagSets         []tag.Set
+}
+
+// MaxStaleness is the maximum amount of time to allow
+// a server to be considered eligible for selection. The
+// second return value indicates if this value has been set.
+func (r *ReadPref) MaxStaleness() (time.Duration, bool) {
+	return r.maxStaleness, r.maxStalenessSet
+}
+
+// Mode indicates the mode of the read preference.
+func (r *ReadPref) Mode() Mode {
+	return r.mode
+}
+
+// TagSets are multiple tag sets indicating
+// which servers should be considered.
+func (r *ReadPref) TagSets() []tag.Set {
+	return r.tagSets
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/results.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/results.go
new file mode 100644
index 0000000..b4bcd02
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/results.go
@@ -0,0 +1,139 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"fmt"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/x/network/result"
+)
+
+// BulkWriteResult holds the result of a bulk write operation.
+type BulkWriteResult struct {
+	InsertedCount int64
+	MatchedCount  int64
+	ModifiedCount int64
+	DeletedCount  int64
+	UpsertedCount int64
+	UpsertedIDs   map[int64]interface{}
+}
+
+// InsertOneResult is a result of an InsertOne operation.
+//
+// InsertedID will be a Go type that corresponds to a BSON type.
+type InsertOneResult struct {
+	// The identifier that was inserted.
+	InsertedID interface{}
+}
+
+// InsertManyResult is a result of an InsertMany operation.
+type InsertManyResult struct {
+	// Maps the indexes of inserted documents to their _id fields.
+	InsertedIDs []interface{}
+}
+
+// DeleteResult is a result of an DeleteOne operation.
+type DeleteResult struct {
+	// The number of documents that were deleted.
+	DeletedCount int64 `bson:"n"`
+}
+
+// ListDatabasesResult is a result of a ListDatabases operation. Each specification
+// is a description of the datbases on the server.
+type ListDatabasesResult struct {
+	Databases []DatabaseSpecification
+	TotalSize int64
+}
+
+func (ldr ListDatabasesResult) fromResult(res result.ListDatabases) ListDatabasesResult {
+	ldr.Databases = make([]DatabaseSpecification, 0, len(res.Databases))
+	for _, spec := range res.Databases {
+		ldr.Databases = append(
+			ldr.Databases,
+			DatabaseSpecification{Name: spec.Name, SizeOnDisk: spec.SizeOnDisk, Empty: spec.Empty},
+		)
+	}
+	ldr.TotalSize = res.TotalSize
+	return ldr
+}
+
+// DatabaseSpecification is the information for a single database returned
+// from a ListDatabases operation.
+type DatabaseSpecification struct {
+	Name       string
+	SizeOnDisk int64
+	Empty      bool
+}
+
+// UpdateResult is a result of an update operation.
+//
+// UpsertedID will be a Go type that corresponds to a BSON type.
+type UpdateResult struct {
+	// The number of documents that matched the filter.
+	MatchedCount int64
+	// The number of documents that were modified.
+	ModifiedCount int64
+	// The number of documents that were upserted.
+	UpsertedCount int64
+	// The identifier of the inserted document if an upsert took place.
+	UpsertedID interface{}
+}
+
+// UnmarshalBSON implements the bson.Unmarshaler interface.
+func (result *UpdateResult) UnmarshalBSON(b []byte) error {
+	elems, err := bson.Raw(b).Elements()
+	if err != nil {
+		return err
+	}
+
+	for _, elem := range elems {
+		switch elem.Key() {
+		case "n":
+			switch elem.Value().Type {
+			case bson.TypeInt32:
+				result.MatchedCount = int64(elem.Value().Int32())
+			case bson.TypeInt64:
+				result.MatchedCount = elem.Value().Int64()
+			default:
+				return fmt.Errorf("Received invalid type for n, should be Int32 or Int64, received %s", elem.Value().Type)
+			}
+		case "nModified":
+			switch elem.Value().Type {
+			case bson.TypeInt32:
+				result.ModifiedCount = int64(elem.Value().Int32())
+			case bson.TypeInt64:
+				result.ModifiedCount = elem.Value().Int64()
+			default:
+				return fmt.Errorf("Received invalid type for nModified, should be Int32 or Int64, received %s", elem.Value().Type)
+			}
+		case "upserted":
+			switch elem.Value().Type {
+			case bson.TypeArray:
+				e, err := elem.Value().Array().IndexErr(0)
+				if err != nil {
+					break
+				}
+				if e.Value().Type != bson.TypeEmbeddedDocument {
+					break
+				}
+				var d struct {
+					ID interface{} `bson:"_id"`
+				}
+				err = bson.Unmarshal(e.Value().Document(), &d)
+				if err != nil {
+					return err
+				}
+				result.UpsertedID = d.ID
+			default:
+				return fmt.Errorf("Received invalid type for upserted, should be Array, received %s", elem.Value().Type)
+			}
+		}
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/session.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/session.go
new file mode 100644
index 0000000..381714d
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/session.go
@@ -0,0 +1,181 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"errors"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/primitive"
+	"github.com/mongodb/mongo-go-driver/mongo/options"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
+	"github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
+	"github.com/mongodb/mongo-go-driver/x/network/command"
+	"github.com/mongodb/mongo-go-driver/x/network/description"
+)
+
+// ErrWrongClient is returned when a user attempts to pass in a session created by a different client than
+// the method call is using.
+var ErrWrongClient = errors.New("session was not created by this client")
+
+// SessionContext is a hybrid interface. It combines a context.Context with
+// a mongo.Session. This type can be used as a regular context.Context or
+// Session type. It is not goroutine safe and should not be used in multiple goroutines concurrently.
+type SessionContext interface {
+	context.Context
+	Session
+}
+
+type sessionContext struct {
+	context.Context
+	Session
+}
+
+type sessionKey struct {
+}
+
+// Session is the interface that represents a sequential set of operations executed.
+// Instances of this interface can be used to use transactions against the server
+// and to enable causally consistent behavior for applications.
+type Session interface {
+	EndSession(context.Context)
+	StartTransaction(...*options.TransactionOptions) error
+	AbortTransaction(context.Context) error
+	CommitTransaction(context.Context) error
+	ClusterTime() bson.Raw
+	AdvanceClusterTime(bson.Raw) error
+	OperationTime() *primitive.Timestamp
+	AdvanceOperationTime(*primitive.Timestamp) error
+	session()
+}
+
+// sessionImpl represents a set of sequential operations executed by an application that are related in some way.
+type sessionImpl struct {
+	*session.Client
+	topo                *topology.Topology
+	didCommitAfterStart bool // true if commit was called after start with no other operations
+}
+
+// EndSession ends the session.
+func (s *sessionImpl) EndSession(ctx context.Context) {
+	if s.TransactionInProgress() {
+		// ignore all errors aborting during an end session
+		_ = s.AbortTransaction(ctx)
+	}
+	s.Client.EndSession()
+}
+
+// StartTransaction starts a transaction for this session.
+func (s *sessionImpl) StartTransaction(opts ...*options.TransactionOptions) error {
+	err := s.CheckStartTransaction()
+	if err != nil {
+		return err
+	}
+
+	s.didCommitAfterStart = false
+
+	topts := options.MergeTransactionOptions(opts...)
+	coreOpts := &session.TransactionOptions{
+		ReadConcern:    topts.ReadConcern,
+		ReadPreference: topts.ReadPreference,
+		WriteConcern:   topts.WriteConcern,
+	}
+
+	return s.Client.StartTransaction(coreOpts)
+}
+
+// AbortTransaction aborts the session's transaction, returning any errors and error codes
+func (s *sessionImpl) AbortTransaction(ctx context.Context) error {
+	err := s.CheckAbortTransaction()
+	if err != nil {
+		return err
+	}
+
+	cmd := command.AbortTransaction{
+		Session: s.Client,
+	}
+
+	s.Aborting = true
+	_, err = driver.AbortTransaction(ctx, cmd, s.topo, description.WriteSelector())
+
+	_ = s.Client.AbortTransaction()
+	return err
+}
+
+// CommitTransaction commits the sesson's transaction.
+func (s *sessionImpl) CommitTransaction(ctx context.Context) error {
+	err := s.CheckCommitTransaction()
+	if err != nil {
+		return err
+	}
+
+	// Do not run the commit command if the transaction is in started state
+	if s.TransactionStarting() || s.didCommitAfterStart {
+		s.didCommitAfterStart = true
+		return s.Client.CommitTransaction()
+	}
+
+	if s.Client.TransactionCommitted() {
+		s.RetryingCommit = true
+	}
+
+	cmd := command.CommitTransaction{
+		Session: s.Client,
+	}
+
+	// Hack to ensure that session stays in committed state
+	if s.TransactionCommitted() {
+		s.Committing = true
+		defer func() {
+			s.Committing = false
+		}()
+	}
+	_, err = driver.CommitTransaction(ctx, cmd, s.topo, description.WriteSelector())
+	if err == nil {
+		return s.Client.CommitTransaction()
+	}
+	return err
+}
+
+func (s *sessionImpl) ClusterTime() bson.Raw {
+	return s.Client.ClusterTime
+}
+
+func (s *sessionImpl) AdvanceClusterTime(d bson.Raw) error {
+	return s.Client.AdvanceClusterTime(d)
+}
+
+func (s *sessionImpl) OperationTime() *primitive.Timestamp {
+	return s.Client.OperationTime
+}
+
+func (s *sessionImpl) AdvanceOperationTime(ts *primitive.Timestamp) error {
+	return s.Client.AdvanceOperationTime(ts)
+}
+
+func (*sessionImpl) session() {
+}
+
+// sessionFromContext checks for a sessionImpl in the argued context and returns the session if it
+// exists
+func sessionFromContext(ctx context.Context) *session.Client {
+	s := ctx.Value(sessionKey{})
+	if ses, ok := s.(*sessionImpl); ses != nil && ok {
+		return ses.Client
+	}
+
+	return nil
+}
+
+func contextWithSession(ctx context.Context, sess Session) SessionContext {
+	return &sessionContext{
+		Context: context.WithValue(ctx, sessionKey{}, sess),
+		Session: sess,
+	}
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/single_result.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/single_result.go
new file mode 100644
index 0000000..9a929db
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/single_result.go
@@ -0,0 +1,93 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
+
+import (
+	"context"
+	"errors"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
+)
+
+// ErrNoDocuments is returned by Decode when an operation that returns a
+// SingleResult doesn't return any documents.
+var ErrNoDocuments = errors.New("mongo: no documents in result")
+
+// SingleResult represents a single document returned from an operation. If
+// the operation returned an error, the Err method of SingleResult will
+// return that error.
+type SingleResult struct {
+	err error
+	cur *Cursor
+	rdr bson.Raw
+	reg *bsoncodec.Registry
+}
+
+// Decode will attempt to decode the first document into v. If there was an
+// error from the operation that created this SingleResult then the error
+// will be returned. If there were no returned documents, ErrNoDocuments is
+// returned.
+func (sr *SingleResult) Decode(v interface{}) error {
+	if sr.err != nil {
+		return sr.err
+	}
+	if sr.reg == nil {
+		return bson.ErrNilRegistry
+	}
+	switch {
+	case sr.rdr != nil:
+		if v == nil {
+			return nil
+		}
+		return bson.UnmarshalWithRegistry(sr.reg, sr.rdr, v)
+	case sr.cur != nil:
+		defer sr.cur.Close(context.TODO())
+		if !sr.cur.Next(context.TODO()) {
+			if err := sr.cur.Err(); err != nil {
+				return err
+			}
+			return ErrNoDocuments
+		}
+		if v == nil {
+			return nil
+		}
+		return sr.cur.Decode(v)
+	}
+
+	return ErrNoDocuments
+}
+
+// DecodeBytes will return a copy of the document as a bson.Raw. If there was an
+// error from the operation that created this SingleResult then the error
+// will be returned. If there were no returned documents, ErrNoDocuments is
+// returned.
+func (sr *SingleResult) DecodeBytes() (bson.Raw, error) {
+	switch {
+	case sr.err != nil:
+		return nil, sr.err
+	case sr.rdr != nil:
+		return sr.rdr, nil
+	case sr.cur != nil:
+		defer sr.cur.Close(context.TODO())
+		if !sr.cur.Next(context.TODO()) {
+			if err := sr.cur.Err(); err != nil {
+				return nil, err
+			}
+			return nil, ErrNoDocuments
+		}
+		return sr.cur.Current, nil
+	}
+
+	return nil, ErrNoDocuments
+}
+
+// Err will return the error from the operation that created this SingleResult.
+// If there was no error, nil is returned.
+func (sr *SingleResult) Err() error {
+	return sr.err
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/util.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/util.go
new file mode 100644
index 0000000..270fa24
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/util.go
@@ -0,0 +1,7 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package mongo
diff --git a/vendor/github.com/mongodb/mongo-go-driver/mongo/writeconcern/writeconcern.go b/vendor/github.com/mongodb/mongo-go-driver/mongo/writeconcern/writeconcern.go
new file mode 100644
index 0000000..234ba19
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/mongo/writeconcern/writeconcern.go
@@ -0,0 +1,186 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package writeconcern
+
+import (
+	"errors"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/bson"
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+	"github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
+)
+
+// ErrInconsistent indicates that an inconsistent write concern was specified.
+var ErrInconsistent = errors.New("a write concern cannot have both w=0 and j=true")
+
+// ErrEmptyWriteConcern indicates that a write concern has no fields set.
+var ErrEmptyWriteConcern = errors.New("a write concern must have at least one field set")
+
+// ErrNegativeW indicates that a negative integer `w` field was specified.
+var ErrNegativeW = errors.New("write concern `w` field cannot be a negative number")
+
+// ErrNegativeWTimeout indicates that a negative WTimeout was specified.
+var ErrNegativeWTimeout = errors.New("write concern `wtimeout` field cannot be negative")
+
+// WriteConcern describes the level of acknowledgement requested from MongoDB for write operations
+// to a standalone mongod or to replica sets or to sharded clusters.
+type WriteConcern struct {
+	w        interface{}
+	j        bool
+	wTimeout time.Duration
+}
+
+// Option is an option to provide when creating a ReadConcern.
+type Option func(concern *WriteConcern)
+
+// New constructs a new WriteConcern.
+func New(options ...Option) *WriteConcern {
+	concern := &WriteConcern{}
+
+	for _, option := range options {
+		option(concern)
+	}
+
+	return concern
+}
+
+// W requests acknowledgement that write operations propagate to the specified number of mongod
+// instances.
+func W(w int) Option {
+	return func(concern *WriteConcern) {
+		concern.w = w
+	}
+}
+
+// WMajority requests acknowledgement that write operations propagate to the majority of mongod
+// instances.
+func WMajority() Option {
+	return func(concern *WriteConcern) {
+		concern.w = "majority"
+	}
+}
+
+// WTagSet requests acknowledgement that write operations propagate to the specified mongod
+// instance.
+func WTagSet(tag string) Option {
+	return func(concern *WriteConcern) {
+		concern.w = tag
+	}
+}
+
+// J requests acknowledgement from MongoDB that write operations are written to
+// the journal.
+func J(j bool) Option {
+	return func(concern *WriteConcern) {
+		concern.j = j
+	}
+}
+
+// WTimeout specifies specifies a time limit for the write concern.
+func WTimeout(d time.Duration) Option {
+	return func(concern *WriteConcern) {
+		concern.wTimeout = d
+	}
+}
+
+// MarshalBSONValue implements the bson.ValueMarshaler interface.
+func (wc *WriteConcern) MarshalBSONValue() (bsontype.Type, []byte, error) {
+	if !wc.IsValid() {
+		return bsontype.Type(0), nil, ErrInconsistent
+	}
+
+	var elems []byte
+
+	if wc.w != nil {
+		switch t := wc.w.(type) {
+		case int:
+			if t < 0 {
+				return bsontype.Type(0), nil, ErrNegativeW
+			}
+
+			elems = bsoncore.AppendInt32Element(elems, "w", int32(t))
+		case string:
+			elems = bsoncore.AppendStringElement(elems, "w", string(t))
+		}
+	}
+
+	if wc.j {
+		elems = bsoncore.AppendBooleanElement(elems, "j", wc.j)
+	}
+
+	if wc.wTimeout < 0 {
+		return bsontype.Type(0), nil, ErrNegativeWTimeout
+	}
+
+	if wc.wTimeout != 0 {
+		elems = bsoncore.AppendInt64Element(elems, "wtimeout", int64(wc.wTimeout/time.Millisecond))
+	}
+
+	if len(elems) == 0 {
+		return bsontype.Type(0), nil, ErrEmptyWriteConcern
+	}
+	return bsontype.EmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
+}
+
+// AcknowledgedValue returns true if a BSON RawValue for a write concern represents an acknowledged write concern.
+// The element's value must be a document representing a write concern.
+func AcknowledgedValue(rawv bson.RawValue) bool {
+	doc, ok := bsoncore.Value{Type: rawv.Type, Data: rawv.Value}.DocumentOK()
+	if !ok {
+		return false
+	}
+
+	val, err := doc.LookupErr("w")
+	if err != nil {
+		// key w not found --> acknowledged
+		return true
+	}
+
+	i32, ok := val.Int32OK()
+	if !ok {
+		return false
+	}
+	return i32 != 0
+}
+
+// Acknowledged indicates whether or not a write with the given write concern will be acknowledged.
+func (wc *WriteConcern) Acknowledged() bool {
+	if wc == nil || wc.j {
+		return true
+	}
+
+	switch v := wc.w.(type) {
+	case int:
+		if v == 0 {
+			return false
+		}
+	}
+
+	return true
+}
+
+// IsValid checks whether the write concern is invalid.
+func (wc *WriteConcern) IsValid() bool {
+	if !wc.j {
+		return true
+	}
+
+	switch v := wc.w.(type) {
+	case int:
+		if v == 0 {
+			return false
+		}
+	}
+
+	return true
+}
+
+// AckWrite returns true if a write concern represents an acknowledged write
+func AckWrite(wc *WriteConcern) bool {
+	return wc == nil || wc.Acknowledged()
+}
