猫鼬模式混合类型字段错误地将 ObjectId 字段保存为字符串



我正在开发聊天应用程序,对话中的每个事件都有一个名为 sender 的字段 - 看起来像这样:

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

每次创建事件时,我都会为发件人字段传递如下所示的对象:

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

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

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

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

这种变化发生得相当频繁,并且同一用户发送的事件在 10 分钟内通过相同的控制器函数表现出这种变化。

猫鼬中是否有某种行为我没有考虑,这会影响 ObjectId 在架构的混合类型字段中的保存方式?

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

所以答案相当模糊,因为它在我们的开发环境中对我们隐藏了。仅当 Node 进程群集时,才会出现此问题,我们仅在生产中真正看到这种情况。事实证明,我们向猫鼬传递了一个字符串版本的user_id,所以问题在于我们对 Redis 存储机制的工作原理缺乏了解。

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

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

希望这对某人有所帮助。

最新更新