go - 使用带有 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 `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/

相关文章:

javascript - 使用 golang 在具有多个条件的 mongo 查询中发出问题

mongodb - 如何在 Go 中使用 .crt 文件通过 ssl 连接到 mongoDB

Goswagger 没有创建适当的 json 规范文件

mongodb - 在 Go 中使用 MongoDb 默认驱动程序创建唯一索引

go - 从文件和存储文件创建 sha256 的最佳模式

testing - 如何重写此 select 语句以保证 100% 的测试覆盖率?

mongodb - mgo $unwind 聚合结果到未知元素种类 (0x2E)

mongodb - 使用 MongoDB 从 Golang 中的子对象数组中获取值

linux - Dockerfile 在构建时找不到 shell 脚本

select - 查询文档并选择子文档