使用mgo对mongoDB中的嵌入式文档进行部分更新

TheoK:

我有以下模型:

type UserModel struct {
    Id        string              `bson:"_id,omitempty"`
    CreatedAt *time.Time          `bson:"createdAt,omitempty"`
    BasicInfo *UserBasicInfoModel `bson:"basicInfo,omitempty"`
}

// *Embedded document*
type UserBasicInfoModel struct {
    FirstName    *string `bson:"firstName,omitempty"`
    LastName     *string `bson:"lastName,omitempty"`
}

我正在使用指针,以便能够区分缺失值(nil)和默认值(例如,字符串,值等)。我也曾经omitempty能够进行部分更新。

当我创建一个用户,我得到以下(正确)回响应:

"id": "aba19b45-5e84-55e0-84f8-90fad41712f6",
"createdAt": "2018-05-26T15:08:56.764453386+03:00",
"basicInfo": {
    "firstName": "Initial first name",
    "lastName": "Initial last name"
}

当我尝试更新文档时,尽管遇到了问题。我将更改作为new发送UserModel,仅更改FirstName嵌入式文档中字段,如下所示:

newFirstName := "New Value"
UserModel{
  BasicInfo: &UserBasicInfoModel{
    FirstName: &newFirstName,
  },
}

我用于执行更新的代码如下:

UpdateId(id, bson.M{"$set": changes})

我得到的答复如下:

"id": "aba19b45-5e84-55e0-84f8-90fad41712f6",
"createdAt": "2018-05-26T12:08:56.764Z",
"basicInfo": {
    "firstName": "New Value",
    "lastName": null
}

createdAt不是null(按我的预期),但是该lastNamenull(这不是我的预期)

我本来希望得到以下信息:

"id": "aba19b45-5e84-55e0-84f8-90fad41712f6",
"createdAt": "2018-05-26T12:08:56.764Z",
"basicInfo": {
    "firstName": "New Value",
    "lastName": "Initial last name"
}

如何使用mgo在子文档中实现部分更新?

icza:

首先,让我们快速解释一下您的createdAt领域。这是您保存的值:2018-05-26T15:08:56.764453386+03:00知道MongoDB以毫秒精度和UTC时区存储日期。因此,从MongoDB中保存和检索的日期变为2018-05-26T12:08:56.764Z,这是“相同”的时刻,仅在UTC区域中,精度被截断为毫秒。

现在开始更新嵌入式文档:

简短而不幸的答案是,我们不能直接使用mgo库和Go模型执行此操作

为什么?

当使用,omitempty选项时,我们将一些指针字段保留为零值(即,是nil),就好像我们使用的类型甚至没有这些字段的值一样。

因此,在您的示例中,如果仅更改BasicInfo.FirstName字段,并且使用此值进行更新,则等效于使用以下结构:

type UserModel struct {
    Id        string              `bson:"_id,omitempty"`
    BasicInfo *UserBasicInfoModel `bson:"basicInfo,omitempty"`
}

type UserBasicInfoModel struct {
    FirstName    *string `bson:"firstName,omitempty"`
}

因此,您发出的update命令的效果如下:

db.users.update({_id: "aba19b45-5e84-55e0-84f8-90fad41712f6"},
    {$set:{
        "_id": "aba19b45-5e84-55e0-84f8-90fad41712f6",
        "basicInfo": {
            "firstName": "New Value"
        }
    }}
)

这是什么意思?将设置_id为相同的值(不会更改),并将basicInfo字段设置为仅具有单个firstName属性的嵌入式文档这将清除lastName嵌入basicInfo文档字段因此,当您在更新后将文档解组为您的UserModel类型的值时,该LastName字段将保留nil(因为MongoDB中不再存在字段)。

我们可以做什么?

展平嵌入式文档

一种简单的解决方案是不使用嵌入式文档,而是将的字段添加UserBasicInfoModelUserModel

type UserModel struct {
    Id        string     `bson:"_id,omitempty"`
    CreatedAt *time.Time `bson:"createdAt,omitempty"`
    FirstName *string    `bson:"firstName,omitempty"`
    LastName  *string    `bson:"lastName,omitempty"`
}

混合,inline选项

此解决方案保留了单独的Go结构,但在MongoDB中,它不会是嵌入式文档(BasicInfo将像上一个示例中一样被展平):

type UserModel struct {
    Id        string             `bson:"_id,omitempty"`
    CreatedAt *time.Time         `bson:"createdAt,omitempty"`
    BasicInfo UserBasicInfoModel `bson:"basicInfo,omitempty,inline"`
}

请注意,BasicInfo如果,inline使用,则必须是非指针这不是问题,因为如果要更改其字段,我们可以将其保留为空结构,因为其字段是指针,因此保留它们nil不会更改它们。

做“手动”更新

如果确实需要使用嵌入式文档,则该mgo库允许您更新嵌入式文档的特定字段,但是您必须“手动”构造更新文档,如本示例所示:

c.UpdateId(Id, bson.M{"$set": bson.M{
    "basicInfo.firstName": newFirstName,
}})

是的,这根本不方便。如果确实确实需要使用不同类型的很多次,则可以创建一个使用反射的实用程序函数,递归遍历这些字段,并从not字段中组装更新文档nil然后,您可以将动态生成的更新文档传递UpdateId()给例如。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在mgo Mongodb中选择所有相同类型的嵌入式文档?

mgo,mongodb:从嵌入式结构中查找与一个字段匹配的文档

使用mgo进行部分更新

mgo,mongodb:查找一个嵌入式文档,该文档是数组的一部分

使用MongoDB和C#新驱动程序版本(2.0)更新集合中的嵌入式文档

更新Mongodb中的嵌入式文档:性能问题?

使用mongoDB将嵌入式文档与父字段进行比较

mongodb聚合中的项目嵌套嵌入式文档

MongoDb更新同一阵列中的多个特定嵌入式文档

基于范围查询MongoDB中嵌入式文档的数组

如何在mongodb中搜索嵌入式文档?

查询Spring Data MongoDB中嵌入式文档的数组

在MongoDB中的多个文档中更新多个嵌入式文档

在mongoDb中对嵌入式文档数组(3个级别)进行过滤查询

更新mongodb中arrays对象的arrays的嵌入式文档

在mongodb nodejs中更新双嵌套的嵌入式文档,而无需使用数字索引

使用C#获取和添加/更新多层嵌入式/嵌套MongoDB文档

MongoDB C#驱动程序-更新嵌入式文档数组中的所有字段

如何在嵌入式数组mongodb中查询嵌入式文档

在mongodb中更新嵌套的嵌入式文档

查询MongoDB中的嵌入式文档

何时使用嵌入式文档MongoDB

嵌入式文档中的批量更新

与数组比较,如何在mongodb中检索部分嵌入式文档?

使用python(pymongo)在mongodb中编辑嵌入式文档

在mongodb中展开嵌入式文档

MongoDB-更新嵌入式文档和文档本身

MongoDB-Mongoose:如何使用Mongoose同时更新两个单独的嵌入式文档?

如何在 MongoDb 中查询嵌入式文档?

TOP 榜单

热门标签

归档