gpt4 book ai didi

mongodb - 在上下文中使用 mgo

转载 作者:数据小太阳 更新时间:2023-10-29 03:13:38 26 4
gpt4 key购买 nike

我一直在为我的 API 使用 mgo,但我在我的 MongoDB 中看到许多当前连接(同时使用少于 5 个设备进行测试)。通过在我的 Mongo 服务器中执行 db.serverStatus().connections,我得到:{ "current": 641, "available": 838219, "totalCreated": 1136 }。下面我在 mgo 的 Github ( Issue #429 ) 中记录了我的问题:

我在 Web 服务器中使用 mgo 的方式是否正确?如果没有,你能给我一个完整的例子吗?

此代码不起作用,几乎可以将其视为伪代码(因为缺少部分,例如导入或配置的来源和模型),但这正是我使用 mgo 的方式。

我必须澄清,我正在构建一个供多个移动设备和网络应用程序使用的 API。

主.go

func main() {
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{config.DatabaseURL},
Timeout: 60 * time.Second,
Database: config.DatabaseName,
Username: config.DatabaseUsername,
Password: config.DatabasePassword,
}

db, err := mgo.DialWithInfo(mongoDBDialInfo)

if err != nil {
log.Fatal("Cannot Dial Mongo: ", err)
}

defer db.Close()
db.SetMode(mgo.Monotonic, true)

phoneIndex := mgo.Index{
Key: []string{"pp"},
Unique: true,
DropDups: true,
Background: true,
Sparse: true,
}

err = db.DB(config.DatabaseName).C("users").EnsureIndex(phoneIndex)
if err != nil {
panic(err)
}

router := mux.NewRouter()
router.HandleFunc("/login", publicWithDB(login, db)).Methods("POST")

if err := http.ListenAndServe(":5000", router); err != nil {
log.Fatal(err)
}
}

func publicWithDB(fn http.HandlerFunc, db *mgo.Session) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
dbsession := db.Copy()
defer dbsession.Close()
fn(w, r.WithContext(context.WithValue(r.Context(), contextKeyDatabase, dbsession)))
}
}

func login(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // Parses the request body
device := r.Form.Get("device")

var deviceid bson.ObjectId
if bson.IsObjectIdHex(device) {
deviceid = bson.ObjectIdHex(device)
}

db := r.Context().Value(contextKeyDatabase).(*mgo.Session)

var device models.Device
err := db.DB(config.DatabaseName).C("devices").FindId(deviceid).One(&device)

w.WriteHeader(200)
w.Write([]byte(utils.ResponseToString(models.Response{Status: 200, Message: "asdasd", Data: device})))

}

我发布这个是因为我找不到完整的实现。

最佳答案

这是一个示例,说明我自己和其他人如何使用 Go 构建 Web 应用程序。此代码未经测试,仅供引用。它缺少导入并且可能有错误。

编辑添加了一个中间件示例。

主.go

package main

func main() {
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{config.DatabaseURL},
Timeout: 60 * time.Second,
Database: config.DatabaseName,
Username: config.DatabaseUsername,
Password: config.DatabasePassword,
}

db, err := mgo.DialWithInfo(mongoDBDialInfo)

if err != nil {
log.Fatal("Cannot Dial Mongo: ", err)
}

defer db.Close()
db.SetMode(mgo.Monotonic, true)

phoneIndex := mgo.Index{
Key: []string{"pp"},
Unique: true,
DropDups: true,
Background: true,
Sparse: true,
}

err = db.DB(config.DatabaseName).C("users").EnsureIndex(phoneIndex)
if err != nil {
panic(err)
}

mgoAdapter := mongo.NewAdapter(db, config.DatabaseName)
deviceStore := mongo.NewDeviceStore(mgoAdapter)
userStore := mongo.NewUserStore(mgoAdapter)

loginController := controllers.NewLoginController(deviceStore)

router := mux.NewRouter()
router.HandleFunc("/login", middleware.AuthorizeUser(userStore)(http.HandlerFunc(loginController.Login)).Methods("POST")

if err := http.ListenAndServe(":5000", router); err != nil {
log.Fatal(err)
}
}

controllers/login.go

package controllers

type LoginController struct {
store DeviceStore
}

func NewLoginController(store stores.DeviceStore) *LoginController {
return &LoginController{
store: store,
}
}

func (c *LoginController) Login(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // Parses the request body
device := r.Form.Get("device")
data, err := c.store.FindByDevice(device)

var respose models.Response
if err != nil {
w.WriteHeader(500)
response = models.Response{Status: 500, Message: fmt.Sprintf("error: %s", err)}
} else if data == nil {
w.WriteHeader(404)
response = models.Response{Status: 404, Message: "device not found"}
} else {
response = models.Response{Status: 200, Message: "device found", Data: data}
}

// Write sets header to 200 if it hasn't been set already
w.Write([]byte(utils.ResponseToString(response)))
}

商店/stores.go

package stores

type DeviceStore interface {
FindByDevice(device string) (*models.Device, error)
}

type UserStore interface {
FindByToken(token string) (*models.User, error)
}

中间件/auth.go

package middleware

func AuthorizeUser(store stores.UserStore) func(h *http.Handler) http.Handler {
return func(h *http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Logic for authorizing user
// Could also store user in the request context
})
}
}

蒙戈/蒙戈.go

package mongo

type Adapter struct {
session *mgo.Session
databaseName string
}

func NewAdapter(session *mgo.Session, dbName string) *Adapter {
return &Adapter{session: session, databaseName: dbName}
}

type deviceStore struct {
*Adapter
}

func NewDeviceStore(adapter *Adapter) stores.DeviceStore {
return &deviceStore{adapter}
}

const devices = "devices"

func (s *deviceStore) FindByDevice(d string) (*models.Device, err) {
sess := s.session.copy()
defer sess.close()

var deviceID bson.ObjectId
if bson.IsObjectIdHex(d) {
deviceID = bson.ObjectIdHex(d)
}

var device models.Device
err := db.DB(s.databaseName).C(devices).FindId(deviceID).One(&device)
if err == mgo.ErrNotFound {
return nil, nil
}
return &device, err
}

type userStore struct {
*Adapter
}

const users = "users"

func NewUserStore(adapter *Adapter) stores.UserStore {
return &userStore{adapter}
}

func (s *userStore) GetUserByToken(token string) (*models.User, error) {
sess := s.session.copy()
defer sess.close()

var user models.User
err := db.DB(s.databaseName).C(users).Find(bson.M{"token": token}).One(&user)
if err == mgo.ErrNotFound {
return nil, nil
}

return &user, err
}

关于mongodb - 在上下文中使用 mgo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43921168/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com