go - BSON 映射到数据库模型结构

标签 go mongo-go

努力找出正确的方法来做到这一点。现在我可以单独将 bson 映射转换为我的数据库模型结构。但现在我只是重复了很多相同的代码。那么有没有更好的方法来做到这一点?

代码示例:

type Agent struct {
    FirstName      string   `bson:"firstName,omitempty" json:"firstName,omitempty"`
    LastName       string   `bson:"lastName,omitempty" json:"lastName,omitempty"`
    ProfileImage   string   `bson:"profileImage,omitempty" json:"profileImage,omitempty"`
}

func BSONToAgent(bsonMap primitive.M) (agent Agent, err error) {
    bsonBytes, err := bson.Marshal(bsonMap)
    if err != nil {
        return agent, err
    }
    bson.Unmarshal(bsonBytes, &agent)
    return agent, nil
}

func BSONArrayToAgents(bsonMap []primitive.M) (agents []Agent, err error) {
    for _, item := range bsonMap {
        agent, err := BSONToAgent(item)
        if err != nil {
            return agents, err
        }
        agents = append(agents, agent)
    }
    return agents, nil
}



type Form struct {
    UserID        primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`
    Name          string             `bson:"name,omitempty" json:"name,omitempty"`
    CreatedAt     time.Time          `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
    UpdatedAt     time.Time          `bson:"updatedAt,omitempty" json:"updatedAt,omitempty"`
}

func BSONArrayToForms(bsonMap []primitive.M) (forms []Form, err error) {
    for _, item := range bsonMap {
        form, err := BSONToForm(item)
        if err != nil {
            return forms, err
        }
        forms = append(forms, form)
    }
    return forms, nil
}

func BSONToForm(bsonMap primitive.M) (form Form, err error) {
    bsonBytes, err := bson.Marshal(bsonMap)
    if err != nil {
        return form, err
    }
    bson.Unmarshal(bsonBytes, &form)
    return form, nil
}




如果您查看 BSONToAgent 和 BSONToForm 函数,它们几乎是相同的函数,只是返回的类型不同。 BSONArrayToAgents 和 BSONArrayToForms 也是如此。现在我想在我的所有数据库模型上实现这些函数,以便轻松转换查询数据库时返回的原语.M(bson 映射)。

有一个更好的方法吗?也许使用接口(interface)?

最佳答案

如果您使用 marshal/unmarshal 作为翻译 bson 的一种方式,您可以这样做:

func BSONToForm(bsonMap primitive.M, out interface{}) (err error) {
    bsonBytes, err := bson.Marshal(bsonMap)
    if err != nil {
        return form, err
    }
    return bson.Unmarshal(bsonBytes, out)
}

var v Form
BSONToForm(bsonMap,&v)

但是,这对于数组来说效果不佳,因此您可以执行以下操作:
func BSONArrayToForms(bsonMap []primitive.M, newItem func() interface{}, add func(interface{})) (err error) {
    for _, item := range bsonMap {
        n:=newItem()
        err := BSONToForm(item,n)
        if err != nil {
            return forms, err
        }
        add(n)
    }
    return nil
}

forms:=make([]Form,0)
BSONArrayToForms(bsonArr,func() interface{} {return &Form{}},func(in interface{}) {
   forms=append(forms,*(in.(*Form)))
})

或单功能变体:
func BSONArrayToForms(bsonMap []primitive.M, newItem func() interface{}) (err error) {
    for _, item := range bsonMap {
        n:=newItem()
        err := BSONToForm(item,n)
        if err != nil {
            return forms, err
        }
    }
    return nil
}

forms:=make([]Form,0)
BSONArrayToForms(bsonArr,func() interface{} {
   forms=append(forms,Form{})
   return &forms[len(forms)-1]})


此版本必须确保返回的指针也存储在数组中。

关于go - BSON 映射到数据库模型结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60269097/

相关文章:

go - ed25519.Public 结果不同

go - 在 Raspberry Pi 上使用 go.dbus 和 omxplayer

mongodb - 如何等待副本追上主副本

mongodb - 如何使用连接池将 mgo session 转换为 mongo-go-driver 客户端?

mongodb - 做一个困难的mongoDB查找

mongodb - 如何导入go的mongo-driver bson

go - 我应该如何重用 Go 中的流?

go - 从给定范围生成组合

go - 模板和自定义函数;错误 : executing "templName" at <"funcName"> is not a define function

mongodb - mongo-go如何使用arrayFilter在 "array of objects inside array of objects"中查找elem