使用嵌套结构和go / mgo进行部分更新

时间:2015-02-27 21:35:00

标签: 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 `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中的记录看起来像这样(正如我所料):

  

{" _id" :ObjectId(" 54f0e231eefbfe049c000001")," a_value" :1," b_value" :2}

但是我想做这样的事情以避免编写冗余函数:

setAValue(42, &b.A)

问题是,这会导致数据丢失,因为它会替换整个条目,而不仅仅是更新它:

  

{" _id" :ObjectId(" 54f0df4eeefbfe0474000001")," a_value" :42}

有没有办法执行这样的更新,而不会消除任何不属于A的值?或者我只是完全以错误的方式解决这个问题?

1 个答案:

答案 0 :(得分:0)

问题是setAValue提交类型A,而不是B.新提交的BSON值不包含B_value

我认为你应该将set function和commit函数分开。您可以通过反射或接口解决此设置和提交问题,但只是拆分功能更简单。