How can i connect mong 1 time and can reuse it ? Go + Mongo

If can , Do you have example project , I really need to learn and use it with production. thx in advance

Have you read the Quickstart?

3 Likes

Sample code that I used many times… Feel free to use it. It is just a draft, it could be not valid as I don’t have a machine with go installed with me today :slight_smile:

// Use interface (cleaner)
type DbStore interface {
	GetDb() *mongo.Database
	GetClient() (*mongo.Client, error)
	Coll(name string, opts ...*options.CollectionOptions) *mongo.Collection
	Disconnect() error
}
type dbStore struct {
	db     *mongo.Database
	client *mongo.Client
}
func NewDbStore(opts *options.ClientOptions, dbName string) (DbStore, error) {
	client, db, err := connect(opts, dbName)
	if err != nil {
		return nil, err
	}
	return &dbStore{db: db, Client: client}, nil
}

func (md *dbStore) GetDb() *mongo.Database {
	return md.db
}

func (md *dbStore) GetClient() (*mongo.Client, error) {
	if md.client != nil {
		return md.client, nil
	}
	return nil, errors.New("client is missing (nil) in Mongo Data Store")
}

func (md *dbStore) Coll(name string, opts ...*options.CollectionOptions) Collection {
	return NewCollection(md.db, name, opts...)
}

func (md *dbStore) Disconnect() error {
	err := md.client.Disconnect(ctx())
	if err != nil {
		return err
	}
	return nil
}
func connect(opts *options.ClientOptions, dbName string) (*mongo.Client, *mongo.Database, error) {
	var connectOnce sync.Once
	var db *mongo.Database
	var client *mongo.Client
	var err error
	connectOnce.Do(func() {
		client, db, err = connectToMongo(opts, dbName)
	})

	return client, db, err
}

func connectToMongo(opts *options.ClientOptions, dbName string) (*mongo.Client, *mongo.Database, error) {
	var err error
	client, err := mongo.NewClient(opts)
	if err != nil {
		return nil, nil, err
	}
	ctx, cancel := context.WithTimeout(context.Background(), defaultConfig.ctxTimeout)
	defer cancel()
	err = client.Connect(ctx)

	if err != nil {
		return nil, nil, err
	}
	err = client.Ping(ctx, readpref.Primary())
	if err != nil {
		_ = client.Disconnect(ctx)
		return nil, nil, errors.New(fmt.Sprintf("Cannot connect do db. Error: %v", err))
	}
	var db = client.Database(dbName)

	return client, db, nil
}

A simple repo

type MyRepo interface{
    Find(ctx context.Context, filters interface{}) []SomeType, error
}

type myRepo struct {
    store      DbStore 
}
func  NewMyRepo(store DbStore) MyRepo {
    return myRepo{ store: store }
}


func (r *myRepo) Find(ctx context.Context , filters interface{}) []Document, error{
    // Query
}

Some file (like main.go or any init file that runs on startup)


var mystore DbStore 
var myRepo MyRepo  
func main() {
  mystore = NewDbStore(yourOptions, "yourDbName")
  myRepo = NewMyRepo(mystore)
  
}

in any file

myRepo.Find(ctx, filter)

Or if you want something more straightforward

import (
    "context"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/mongo/readpref"
)

// Global var
var client *mongo.Client

func main() {
  
  ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  defer cancel()
  client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
  
}

In some file

func PerformSomethingWithClient() {
   client.XXXXX()
}