【问题标题】:Dollar prefixed field not valid for storage美元前缀字段对存储无效
【发布时间】:2020-02-12 11:01:55
【问题描述】:

我收到了这个错误:

panic: multiple write errors: [{write errors: [{The dollar ($) prefixed field '$set' in 'conversations.newest_message.$set' is not valid for storage.}]}, {<nil>}]

这是我要更新的数据,我要更新对话中的最新消息:

{
    "_id" : "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
    "conversations" : [ 
        {
            "conversation_id" : "VOoHg7nY4xBcrQtzxokbM9aStSSqei44",
            "newest_message" : {
                "user_name" : "",
                "data" : {
                    "description" : "",  
                },
            }
        }
    ]
}

这里是 mongoldb 查询:

db.collectionA.update(
    {
        _id: "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1", 
        "conversations.conversation_id": "VOoHg7nY4xBcrQtzxokbM9aStSSqei44"
    },
    {
        "$set": {
            "conversations.$.newest_message": {new_update_data_here}
    }
)

这里是 Golang 代码,我使用的是 mongodb 驱动程序而不是 mgo:

filter = bson.M{
                    "_id":                           id,
                    "conversations.conversation_id": messageReceived.ConversationID,
                }
update = bson.M{
                    "$set": bson.M{
                        "conversations": bson.M{
                            "newest_message": newestMessage,
                        },
                    },
                }

_, err = d.DB.Collection(collectionUserInformation).UpdateOne(ctx, filter, update)
            if err != nil {
                panic(err)
            }

【问题讨论】:

  • 你有哪个 mongo 版本?
  • 你最后一个代码块中newestMessage的值是多少,你确定你没有在某处设置bson.M{"$set": .....}
  • @tarrsalah 我的版本是:MongoDB shell version v4.2.1
  • @topenion 我的 latest_message 变量看起来像这样,它与上面 mongodb 查询命令中的 new_update_data_here 相同:{“user_name”:“David”,“data”:{“description”:“这是消息", }, } 而且我很确定 var update 是我第一次使用 operator $set
  • @SPM 这是我向您展示整个 mongodb 查询和 Golang 代码的链接:codeshare.io/5PMjWd

标签: mongodb go


【解决方案1】:

example中的文档用作初始文档:

{
        "_id" : "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
        "settings" : {
                "general" : {
                        "languages" : [
                                {
                                        "label" : "English",
                                        "value" : "eng"
                                }
                        ],
                        "contact" : "No one",
                        "language" : [
                                {
                                        "label" : "English",
                                        "value" : "eng"
                                },
                                {
                                        "label" : "English",
                                        "value" : "eng"
                                }
                        ]
                },
                "block_list" : [
                        "qGXVFjeZeFwrZjURfcZHqkCbgO91Gbu87KXx3Ba5",
                        "hFkF7DjPwBB6G2qbNT0J1ZROd3rxNLrZ5zt-HmMK"
                ],
                "auto_reply" : {
                        "set_auto_reply" : false,
                        "auto_reply_messages" : [ ]
                }
        },
        "conversations" : [
                {
                        "conversation_id" : "VOoHg7nY4xBcrQtzxokbM9aStSSqei44",
                        "people" : [
                                {
                                        "user_id" : "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
                                        "user_name" : "Dat Vo"
                                },
                                {
                                        "user_id" : "qGXVFjeZeFwrZjURfcZHqkCbgO91Gbu87KXx3Ba5",
                                        "user_name" : "An Son"
                                }
                        ],
                        "newest_message" : {
                                "user_name" : "",
                                "data" : {
                                        "description" : "",
                                        "host" : "",
                                        "image" : "",
                                        "title" : "",
                                        "type" : "",
                                        "url" : "",
                                        "youtube_video_id" : ""
                                },
                                "seen" : false
                        }
                }
        ]
}

您可以使用$set$ positional operator 替换conversations 数组中的newest_message 元素:

更新 := bson.M{ "$set": bson.M{ "conversations.$.newest_message": bson.M{...

ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()

filter := bson.M{
    "_id":                           "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
    "conversations.conversation_id": "VOoHg7nY4xBcrQtzxokbM9aStSSqei44",
}
update := bson.M{
    "$set": bson.M{
        "conversations.$.newest_message": bson.M{
            "message_id": "saisa",
            "user_id":    "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
            "user_name":  "Dat Vo",
            "content":    "this is the new msg",
            "created_at": "12345678",
            "seen":       false,
        },
    },
}

_, err2 := d.DB.Collection(collectionUserInformation).UpdateOne(ctx, filter, update)
if err2 != nil {
    panic(err2)
}

它将返回以下更新的文档:

{
        "_id" : "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
        "settings" : {
                "general" : {
                        "languages" : [
                                {
                                        "label" : "English",
                                        "value" : "eng"
                                }
                        ],
                        "contact" : "No one",
                        "language" : [
                                {
                                        "label" : "English",
                                        "value" : "eng"
                                },
                                {
                                        "label" : "English",
                                        "value" : "eng"
                                }
                        ]
                },
                "block_list" : [
                        "qGXVFjeZeFwrZjURfcZHqkCbgO91Gbu87KXx3Ba5",
                        "hFkF7DjPwBB6G2qbNT0J1ZROd3rxNLrZ5zt-HmMK"
                ],
                "auto_reply" : {
                        "set_auto_reply" : false,
                        "auto_reply_messages" : [ ]
                }
        },
        "conversations" : [
                {
                        "conversation_id" : "VOoHg7nY4xBcrQtzxokbM9aStSSqei44",
                        "people" : [
                                {
                                        "user_id" : "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
                                        "user_name" : "Dat Vo"
                                },
                                {
                                        "user_id" : "qGXVFjeZeFwrZjURfcZHqkCbgO91Gbu87KXx3Ba5",
                                        "user_name" : "An Son"
                                }
                        ],
                        "newest_message" : {
                                "created_at" : "12345678",
                                "seen" : false,
                                "message_id" : "saisa",
                                "user_id" : "iNIXU8dgLgg-KdC3FE1hX8qBpY44hTF-2m-h-RG1",
                                "user_name" : "Dat Vo",
                                "content" : "this is the new msg"
                        }
                }
        ]
}

您之前的尝试是用一个仅包含 newest_message 的文档 conversations 替换文档的 conversations 数组。您想将 $set 运算符与提供完整路径的位置 $ 运算符一起使用,这样它就可以替换您想要的子文档。

【讨论】:

  • 感谢大家的支持,终于找到原因了。因为我用来存储 latest_message 的变量在另一个 goroutine 中被修改(我使用 goroutines 来同时连接到多个集合)并且我完全忘记了它,所以我认为它的值与我展示给你的一样。再次感谢您花时间解决此问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2017-12-13
  • 2019-12-27
  • 2023-03-27
  • 2020-05-24
  • 1970-01-01
相关资源
最近更新 更多