【问题标题】:When does a deprecated field in a MongoDB document get deleted?MongoDB 文档中已弃用的字段何时被删除?
【发布时间】:2021-01-01 13:11:58
【问题描述】:

我使用 NodeJS、MongoDB 和 Mongoose。我将字段从字符串更改为字符串数组。一个月前,我有:

// Before.
const UserSchema = new Schema({
  ip: String
});

从上周开始,我有:

// After.
const UserSchema = new Schema({
  ips: [String]
});

由于我保存该字段的日常脚本,现在所有文档都没有字段ip。我假设当 NodeJS 加载用户对象时,它使用最新的模式;当它保存对象时,它会覆盖任何以前的文档。所以我希望之前的字段ip 不会在user.save() 的更新中继续存在。

这是真的吗?如果NodeJS只加载一个文档不保存,会不会保留原来的ip字段?

更新:按照建议的评论,我最终得到了一个包含两个版本的文档:

> db.users.find({ip: {$ne: null}}, {ip: 1, ips: 1}).pretty()
{ "_id" : ObjectId("5f065633404c3e4aaac69142"), "ip" : "::1" }
{
    "_id" : ObjectId("5f30773f86a1993db449e1b3"),
    "ip" : "::1",
    "ips" : [
        "::1"
    ]
}

如果它包含ips,那么它已经使用新模式保存了对象。所以我不明白原始字段ip何时被覆盖。

【问题讨论】:

  • 测试一下就知道了?

标签: node.js mongodb mongoose mongoose-schema


【解决方案1】:

经过一番戳,不推荐使用的字段没有被删除,但我无法从 NodeJS 访问它,因为它在架构中丢失了。下面是一个静态方法的例子:

// Get all users.
UserSchema.statics.getAllUsers = function() {
  try {
    // Return all users.
    return User.find()
      .sort({created: -1})
      .exec();
  } catch (err) {
    console.log(err);
  }
};

UserSchema.statics.inspect = async function() {
  let users = await this.getAllUsers();

  for (let user of users) {
    console.log("IP = " + user.ip);
    console.log("user = " + user.toString());
  }
  return;
}

结果是:

IP = 未定义 用户 = { _id: 5f4e7..., ip: '::ffff:...', ... }

所以不推荐使用的字段没有被删除。当我将它重新添加到 Mongoose 架构中时,我能够从 NodeJS 代码再次访问它。

【讨论】:

    【解决方案2】:

    只需使用 push 方法将新 ip 添加到 ips 字段。浏览这个例子

    const user = require('../your model');
    
    const findingUser = await user.findOne(id);
    
    const updateUser  = findingUser.ips.push(newIp);
    
    updateUser.save()
    
    

    现在它不会覆盖,而是添加新 IP。

    【讨论】:

    • 是的,这段代码有效,我能够将恢复的数据保存在数组中。我对 MongoDB 中如何保存和覆盖文档的机制更感兴趣。
    猜你喜欢
    • 2015-07-30
    • 2020-11-21
    • 2023-04-09
    • 2012-01-28
    • 2011-10-14
    相关资源
    最近更新 更多