【问题标题】:Mongoose schema mixed type field errantly saving ObjectId field as a StringMongoose 模式混合类型字段错误地将 ObjectId 字段保存为字符串
【发布时间】:2015-01-17 10:10:14
【问题描述】:

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

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

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

{
    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 中是否存在某种我没有考虑到的行为,这会影响 ObjectId 在 Schema 的混合类型字段中的保存方式?

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

【问题讨论】:

  • 为什么要使用混合类型而不是在架构中添加 usernameuser_id 字段?
  • @JohnnyHK 那是我们早期采取的路线。知道这种变化的原因可能是什么吗?
  • 没有线索。除非您可以提供重现它的示例代码,否则我不确定我们能提供什么帮助。
  • @JohnnyHK 想通了,原来这不是猫鼬问题。无论如何感谢您的回复。

标签: node.js mongodb mongoose objectid


【解决方案1】:

所以答案相当模糊,因为它在我们的开发环境中对我们隐藏。该问题仅在 Node 进程集群时出现,我们仅在生产中真正看到。原来我们传递给 Mongoose 的是一个字符串化版本的 user_id,所以问题在于我们对 Redis Store 机制的工作原理缺乏了解。

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

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

希望这可以帮助某人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-13
    • 2016-07-27
    • 2021-05-06
    • 1970-01-01
    • 2014-12-12
    • 2019-06-23
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多