【问题标题】:Update single sub document in multiple array in mgo更新mgo中多个数组中的单个子文档
【发布时间】:2017-08-03 06:22:12
【问题描述】:

我有以下 mongodb (3.4.x) 文档,我在 golang 中使用 mgo 驱动程序编写代码

{
"id": "5981d4c2795a1b4a801ee027",
"scenarioId": "59804b10d8ee910085e33865",
"messages": [
    {
        "id": "5981d4c2795a1b4a801ee028",
        "toQueue": [
            {
                "id": "5981d4c2795a1b4a801ee029",
                "to": {
                    "email": "some@email.com"
                },
                "channel": "EMAIL",
                "toType": "EMAIL",
                "status": {
                    "id": 1,
                    "groupId": 1,
                    "groupName": "PROCESSING",
                    "name": "APPROVED",
                    "description": "MessageChain approved for processing"
                }
            },
            {
                "id": "5981d4c2795a1b4a801ee02a",
                "to": {
                    "phone": "+381631891245"
                },
                "channel": "SMS",
                "toType": "PHONE",
                "status": {
                    "id": 1,
                    "groupId": 1,
                    "groupName": "PROCESSING",
                    "name": "APPROVED",
                    "description": "MessageChain approved for processing"
                }
            }
        ],
        "status": {
            "id": 1,
            "groupId": 1,
            "groupName": "PROCESSING",
            "name": "APPROVED",
            "description": "MessageChain approved for processing"
        }
    },
    {
        "id": "5981d4c2795a1b4a801ee02b",
        "toQueue": [
            {
                "id": "5981d4c2795a1b4a801ee02c",
                "to": {
                    "phone": "+123456789"
                },
                "channel": "SMS",
                "toType": "PHONE",
                "status": {
                    "id": 1,
                    "groupId": 1,
                    "groupName": "PROCESSING",
                    "name": "APPROVED",
                    "description": "MessageChain approved for processing"
                }
            }
        ],
        "status": {
            "id": 1,
            "groupId": 1,
            "groupName": "PROCESSING",
            "name": "APPROVED",
            "description": "MessageChain approved for processing"
        }
    }
],
"messageStages": [
    {
        "id": "5981d4c2795a1b4a801ee033",
        "validityPeriod": 5,
        "validityPeriodTimeUnit": "MINUTES",
        "providerId": 5,
        "email": {
            "text": "this is the email text",
            "subject": "and here the email subject"
        },
        "status": {
            "id": 1,
            "groupId": 1,
            "groupName": "PROCESSING",
            "name": "APPROVED",
            "description": "MessageChain approved for processing"
        }
    }
]

}

我知道messages.$.toQueue.id的值,我想更新相关toQueue数组项中的status.id。

我试图这样做:

query = bson.M{
    "messages.toQueue._id": toQueueId,
}

update = bson.M{
    "$set": bson.M{
        "messages.$.toQueue.$.status.id": status.Id,
        "messages.$.toQueue.$.status.name": status.Name,
        "messages.$.toQueue.$.status.groupId": status.GroupId,
        "messages.$.toQueue.$.status.groupName": status.GroupName,
        "messages.$.toQueue.$.status.description": status.Description,

    },
}
err = cr.Update(query,update)

但不允许使用多个 $。没有它也不能更新。

有没有办法只更新我在查询中找到的子文档?

【问题讨论】:

  • 您正在尝试更新“嵌套数组”。 不要使用“嵌套数组”positional $ operator 只能匹配找到的 "first" 索引,而 always 仅表示“外部”数组。实际上,您从不需要“嵌套”。无论您希望实现什么,总是可以通过将“属性”放置在“单一”数组项上来更好地处理,这些项将代表您“认为”嵌套为您所做的任何事情。嵌套不会“分类”。不是第一个问的,这是一个常见的设计错误。改变设计。
  • 我同意,该文档被过度嵌入。一个快速的收获是将单个消息(电子邮件、电话)放在自己的集合中,并引用单个消息所属的父级。

标签: mongodb go mongodb-query mgo


【解决方案1】:

Neil Lunn 给出了正确的答案。 无法像我尝试的那样使用嵌套数组。他也是对的,这个问题来自设计错误。 所以我按照他和 Markus W Mahlberg 的建议将其更改为将 toQueue 部分移到单独的集合中,并以 messageId 作为参考。

【讨论】:

    猜你喜欢
    • 2019-08-02
    • 2014-09-25
    • 2020-12-11
    • 2015-12-22
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    相关资源
    最近更新 更多