Mongoose模式混合类型字段错误地将ObjectId字段保存为String

时间:2014-11-19 18:43:23

标签: node.js mongodb mongoose objectid

我正在处理聊天应用程序,对话中的每个事件都有一个名为sender的字段 - 如下所示:

var eventSchema = Schema({
    sender: {
        type: {}, //username && user_id fields
        required: true
    }
}

每次创建一个Event时,我都会在sender字段中传入看起来像这样的对象:

{
    username: String,
    user_id: ObjectId("")
}

我很肯定每次Event.sender中的user_id字段都是ObjectId类型。

但是,在数据库中,保存的事件有时具有String&&类型的Event.sender.user_id。其他时候Event.sender.user_id保存为ObjectId()类型。

{
    username: String,
    user_id: ObjectId("")    // sometimes it saves like this
}

{
    username: String,
    user_id: String    // other times it saves like this
}

变化发生得相当频繁,并且有同一个用户发送的事件,在10分钟的时间内通过相同的控制器功能显示出这种变化。

在Mongoose中是否存在某种行为,我没有考虑哪种行为会影响ObjectIds在Schema的混合类型字段中的保存方式?

此行为发生在保存,而不是更新。系统内的Event.sender字段没有更新。

1 个答案:

答案 0 :(得分:1)

所以答案相当模糊,因为它在我们的开发环境中对我们隐藏起来。仅当Node流程是群集的时才会出现此问题,我们只在生产中看到这一点。事实证明我们正在向Mongoose传递一个字符串化版本的user_id,所以问题在于我们对Redis Store机制的工作方式缺乏了解。

在生产中,我们使用redis存储来管理socket.io的Node进程之间的会话。因此,在握手过程中,http请求可能会使其进入与您最初开始握手的进程不同的进程。然后,Redis Store将握手对象字符串化并将其发送到所有其他正在运行的进程。

由于stringify,我们在应用程序中的许多地方使用的user_id上的ObjectId包装器都会丢失,我们最终会在发送方对象中保存字符串以用于我们的许多事件。

希望这可以帮助有人下线。