我正在尝试通过使用嵌套结构来最大限度地跨对象共享数据的代码重用。考虑以下代码:
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
的值?还是我完全以错误的方式解决了这个问题?
最佳答案
这是 setAValue
中的问题,您提交类型 A,而不是 B。新提交的 BSON 值不包含 B_value
。
我认为您应该将设置功能和提交功能分开。您可以通过反射或接口(interface)解决此设置和提交问题,但仅拆分功能更简单。
关于go - 使用带有 go/mgo 的嵌套结构进行部分更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28774705/