【问题标题】:Mongoose and mongoDB - duplicate key errorMongoose 和 mongoDB - 重复键错误
【发布时间】:2015-05-01 03:01:23
【问题描述】:

我正在尝试将 MongoDB 和 mongoose 用于我的小型对话应用程序,其中每个用户都有自己的集合,但在保存新对话时出现错误:

错误:MongoError: insertDocument :: 由 :: 11000 E11000 重复键错误索引:chat.privatemessages.$id dup key: { : ObjectId('54f1a39ff467833f7e794636') }

我的架构:

    var chatPrivateMessagesSchema = mongoose.Schema({
    user: String,
    with:[{
        conversation_with: String,
        messages:[{
            text:String,
            created: {type: Date, default: Date.now}
        }]
    }]
});

var PrivateMessages = mongoose.model('PrivateMessages', chatPrivateMessagesSchema);

保存新对话的方法:

socket.on ('chat', function (from, to, message, callback) {
    PrivateMessages.find ({}, function (err, users) {
        if (err) throw err;
        for (var i = 0; i < users.length; i++) {
            if (users[i].user == from) {
                var newPrivateMsg = new PrivateMessages ({_id: users[i]._id}, {
                    with: [{
                        conversation_with: to, //if conversation with "to" user does not exist create a new entry
                        messages: [{
                            text: message, //append a new message 
                            created: {type: Date, default: Date.now}
                        }]
                    }]
                });
                newPrivateMsg.save (function (err) {
                    if (err) throw err;
                });
            }
        }
    });
});

所以基本上我正在寻找的输出应该是这样的?

{
    "_id": "some id",
    "user": "John",
    "with": [{
        "conversation_with": "Maria",
        "_id": "some id",
        "messages": [{
            "text": "Hellomyfisrtmessage",
            "created": "somedate"
        }, {
            "text": "Secondmessage ",
            "created": "somedate"
        }, {
            "text": "Thirdmessage",
            "created": "somedate"
        }, ]
    }, {
        "conversation_with": "Peter",
        "_id": "some id",
        "messages": [{
                "text": "Hellomyfisrtmessage",
                "created": "somedate"
            }, {
                "text": "Secondmessage ",
                "created": "somedate"
            }, {
                "text": "Third message",
                "created": "some date"
            },

        ]
    }],

}

我真的很苦恼如何插入一个新条目:(有人可以帮忙吗?

【问题讨论】:

    标签: node.js mongodb mongoose socket.io


    【解决方案1】:

    问题是您将每个 PrivateMessage _id 设置为用户的 _id,不要那样做!

    编辑:

    socket.on ('chat', function (from, to, message, callback) {
        PrivateMessages.find ({}, function (err, users) {
            if (err) throw err;
            for (var i = 0; i < users.length; i++) {
                if (users[i].user == from) {
                    users[i].with.forEach(function(with){
                        if (with.conversation_with === to ){
    
                            // append new message
                            with.messages.push({
                                text: message,
                                created: { type: Date, default: Date.now }
                            })
                        }
                    })
    
                    users[i].save (function (err) {
                        if (err) throw err;
                    });
    
                }
            }
        });
    });
    

    【讨论】:

    • 感谢@Yuri,但您的解决方案是每次为同一个用户添加一个新条目。我需要为同一用户保留相同的条目,只需在 conversation_with: to 中为该特定人员添加一条新消息
    • 所以,您最初的问题涉及插入,但您真正想要的是更新,可能插入(如果不存在?)。我已经更新了我的答案,向您展示如何完成这样的事情。但是您可能必须对其进行修改以包含一个条件,其中 conversation_with 不匹配 "to" ,在这种情况下您需要创建一个。我强烈建议您简化架构,不需要 2 个嵌套数组。
    • 非常感谢@Yuri,这正是我所需要的。你太棒了。虽然,我刚刚意识到架构可能不是存储两个人之间对话的最佳解决方案,因为我只保存一个人的消息,然后我需要检索两个用户的消息。我需要为此努力。但无论如何,再次感谢。
    • 顺便说一句,你知道两个人之间有什么合适的对话模式吗?
    • 尽可能简化通常是个好主意。至于两个人之间的对话,“对话”实际上是一个抽象概念,象征着两个人之间的消息集合,并且可以使用查询轻松建模。我的架构可能只是{发件人:ObjectId,收件人:ObjectId,消息:字符串}。发件人/收件人是 ObjectId 的衬里到他们各自的用户 ID。插入变得微不足道(只需调用 new 并保存)。要按用户查找对话,只需查询其中发件人或收件人 == 用户 ID,然后进行一些基本的数组操作。
    猜你喜欢
    • 2018-10-12
    • 2020-09-29
    • 2014-04-16
    • 2018-01-19
    相关资源
    最近更新 更多