使用带有go/mgo的嵌套结构进行部分更新

使用带有go/mgo的嵌套结构进行部分更新,go,mgo,Go,Mgo,我正试图通过使用嵌套结构最大限度地提高共享数据的对象之间的代码重用。考虑下面的代码: package main import ( "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) var collection *mgo.Collection type Identifiable interface { GetId() bson.ObjectId } type A struct { Id bson.ObjectId `bso

我正试图通过使用嵌套结构最大限度地提高共享数据的对象之间的代码重用。考虑下面的代码:

package main

import (
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

var collection *mgo.Collection

type Identifiable interface {
    GetId() bson.ObjectId
}

type A struct {
    Id bson.ObjectId `bson:"_id"`
    A_value int
}

type B struct {
    A `bson:",inline"`
    B_value int
}

func (self *A) GetId() bson.ObjectId {
    return self.Id
}

func setAValue(value int, a *A) {
    a.A_value = value
    commit(a)
}

func commit(i Identifiable) {
    collection.UpsertId(i.GetId(), i)
}

func main() {
    session, _ := mgo.Dial("localhost")
    collection = session.DB("test").C("my_collection")

    b := B{A: A{Id: bson.NewObjectId(), A_value: 1}, B_value: 2}
    commit(&b)
}
此时,mongo中的记录如我所料:

{u id:objectid54f0e231eefbfe049c00001,a_值:1,b_值:2}

但是,为了避免编写冗余函数,我想这样做:

setAValue(42, &b.A)
问题在于,这会导致数据丢失,因为它会替换整个条目,而不仅仅是更新条目:

{u id:objectid54f0df4eeefbfe04740000001,a_值:42}

有没有一种方法可以执行这样的更新,而不会吹走任何不属于某个应用程序的值?还是我完全走错了方向?

这是setAValue中的问题,您提交的是类型A,而不是B。新提交的BSON值不包含B_值

我认为应该将set函数和commit函数分开。您可以通过反射或接口来解决此集合和提交问题,但仅拆分功能更简单