为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中重用 MongoDB 连接

如何在 Go 中重用 MongoDB 连接

Go
慕容3067478 2023-07-31 10:58:27
我想将用 Go 编写的服务器与 MongoDB 连接,但我不知道如何以有效的方式做到这一点。我发现几个例子实现了它,如下所示。库/mongodb/client.gopackage mongodbimport (    "context"    "log"    "project/keys"    "go.mongodb.org/mongo-driver/mongo"    "go.mongodb.org/mongo-driver/mongo/options")func GetClient() *mongo.Database {    client, err := mongo.Connect(        context.Background(),        options.Client().ApplyURI(keys.GetKeys().MONGO_URI),    )    if err != nil {        log.Fatal(err)    }    return client.Database(keys.GetKeys().MONGO_DB_NAME)}服务/用户/findOne.gopackage userservicesimport (    "context"    "log"    "project/libs/mongodb"    "project/models"    "go.mongodb.org/mongo-driver/bson")func FindOne(filter bson.M) (models.User, error) {    var user models.User    collection := mongodb.GetClient().Collection("users")    result := collection.FindOne(context.TODO(), filter)    if result.Err() != nil {        return user, result.Err()    }    if err := result.Decode(&user); err != nil {        log.Println("Failed to decode user with error:", err)        return user, err    }    return user, nil}该GetClient函数返回一个数据库实例,然后在整个应用程序中使用该实例。这似乎有效,但我想知道这是否真的是最佳实践,因为每次请求新客户端时似乎都会创建一个新连接,如第二个代码片段所示,或者该假设是否不正确?我还考虑过转换GetClient为单例,它总是返回相同的数据库实例,但在这种情况下如何处理丢失的连接?谢谢
查看完整描述

3 回答

?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

我就是这样做的。在服务启动时执行一次,然后将 MongoDatastore 对象传递给编排器、服务层和存储库层。我正在使用 mongo 的“github.com/mongodb/mongo-go-driver/mongo”驱动程序。我认为它在内部监视并回收空闲连接。因此,只要对 mongo.Client 对象的引用不丢失,我们就不必担心连接中断。



const CONNECTED = "Successfully connected to database: %v"


type MongoDatastore struct {

    db      *mongo.Database

    Session *mongo.Client

    logger  *logrus.Logger

}


func NewDatastore(config config.GeneralConfig, logger *logrus.Logger) *MongoDatastore {


    var mongoDataStore *MongoDatastore

    db, session := connect(config, logger)

    if db != nil && session != nil {


        // log statements here as well


        mongoDataStore = new(MongoDatastore)

        mongoDataStore.db = db

        mongoDataStore.logger = logger

        mongoDataStore.Session = session

        return mongoDataStore

    }


    logger.Fatalf("Failed to connect to database: %v", config.DatabaseName)


    return nil

}


func connect(generalConfig config.GeneralConfig, logger *logrus.Logger) (a *mongo.Database, b *mongo.Client) {

    var connectOnce sync.Once

    var db *mongo.Database

    var session *mongo.Client

    connectOnce.Do(func() {

        db, session = connectToMongo(generalConfig, logger)

    })


    return db, session

}


func connectToMongo(generalConfig config.GeneralConfig, logger *logrus.Logger) (a *mongo.Database, b *mongo.Client) {


    var err error

    session, err := mongo.NewClient(generalConfig.DatabaseHost)

    if err != nil {

        logger.Fatal(err)

    }

    session.Connect(context.TODO())

    if err != nil {

        logger.Fatal(err)

    }


    var DB = session.Database(generalConfig.DatabaseName)

    logger.Info(CONNECTED, generalConfig.DatabaseName)


    return DB, session

}


您现在可以按如下方式创建存储库:-


type TestRepository interface{

    Find(ctx context.Context, filters interface{}) []Document, error

}


type testRepository struct {

    store      *datastore.MongoDatastore

}


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

    cur, err := r.store.GetCollection("some_collection_name").Find(ctx, filters)

    if err != nil {

        return nil, err

    }

    defer cur.Close(ctx)

    var result = make([]models.Document, 0)

    for cur.Next(ctx) {

        var currDoc models.Document

        err := cur.Decode(&currDoc)

        if err != nil {

            //log here

            continue

        }

        result = append(result, currDoc)

    }

    return result, err

}


查看完整回答
反对 回复 2023-07-31
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

我这样做解决了它


var CNX = Connection()

func Connection() *mongo.Client {

    // Set client options

    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")


    // Connect to MongoDB

    client, err := mongo.Connect(context.TODO(), clientOptions)


    if err != nil {

        log.Fatal(err)

    }


    // Check the connection

    err = client.Ping(context.TODO(), nil)


    if err != nil {

    log.Fatal(err)

    }


    fmt.Println("Connected to MongoDB!")


    return client

  }


//calll connection

 func main() {

      collection := db.CNX.Database("tasks").Collection("task")

 }


output "Connected to MongoDB!"


查看完整回答
反对 回复 2023-07-31
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

我所做的是这样的:


我有一个app.go文件来在我创建的config文件夹中建立mongoDB 连接


func Connection() *mongo.Client {

if err := godotenv.Load(); err != nil {

    log.Println("No .env file found")

}

uri := os.Getenv("MONGODB_URI")

if uri == "" {

    log.Fatal("You must set your 'MONGODB_URI' environmental variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable")

}

// Set client options

clientOptions := options.Client().ApplyURI(uri)


// Connect to MongoDB

client, err := mongo.Connect(context.TODO(), clientOptions)


if err != nil {

    log.Fatal(err)

}


// Check the connection

err = client.Ping(context.TODO(), nil)


if err != nil {

    log.Fatal(err)

}


fmt.Println("Connected to MongoDB!")


return client

}

我在另一个名为employee.go的文件中调用了这个函数,该文件位于模型文件夹中


var CNX = config.Connection()


func (e *Employee) CreateEmployeeDetails() *Employee {

    coll := CNX.Database("employee").Collection("detail")

    fmt.Println(coll)

    result, err := coll.InsertOne(context.TODO(), e)

    fmt.Printf("Inserted document with _id: %v\n", result.InsertedID)

    if err != nil {

        panic(err)

    }


    return e

}



查看完整回答
反对 回复 2023-07-31
  • 3 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信