向架构添加新字段后如何更新旧文档?

Posted

技术标签:

【中文标题】向架构添加新字段后如何更新旧文档?【英文标题】:How to update old documents after adding new fields to the schema? 【发布时间】:2021-06-21 09:38:51 【问题描述】:

假设我有一个如下所示的 user 架构:

const userSchema = new mongoose.Schema(
    username: 
        type: String,
        required: true,
    ,
    password: 
        type: String,
        required: true
    
);

然后一些人在网站上注册并创建了user 文档。

然后在未来的某个时候,我将这些附加字段添加到 user 架构中:


    joinedAt: 
        type: Data,
        default: Date.now,
    ,
    about: 
        type: String,
        required: true,
    

我应该如何更新旧数据?我来自django,在django,我只运行python3 manage.py makemigrations,如果不需要或具有默认值(如本例中的joinedAt),它将对所有现有数据应用更改。

但如果没有(如本例中的 about 字段),那么它会问我现有字段的值应该是什么。

在 Node.js 中是如何实现的?

【问题讨论】:

【参考方案1】:

只需像这样编写一个 MongoDb 更新查询:

let about = "Whatever you want";

db.users.updateMany(
    
        joinedAt:  $exists: false ,
        about:  $exists: false ,
    ,
    
        $set: 
            joinedAt: new Date(),
            about: about
        
    
);

如果你想要一个 Node.js 脚本,那么:

第一步:创建文件user_migration.js

const MongoClient = require('mongodb').MongoClient;
const DB_URI = "mongodb://localhost:27017/myDB";

const options = 
  useNewUrlParser: true
;

MongoClient.connect(DB_URI, options, (err, client) => 
  if (err) 
    console.log("ERROR: Failed to connect to database.");
    console.log(err);
    return;
  

  let dbName = DB_URI.split("/", -1).pop();
  let db = client.db(dbName);

  console.log(`Connected to $dbName database successfully.`);

  let about = "Whatever you want";
  db
    .collection('users')
    .updateMany(
      
        joinedAt:  $exists: false ,
        about:  $exists: false ,
      ,
      
        $set: 
          joinedAt: new Date(),
          about: about
        
      
    )
    .then(res => 
      // console.log(res);
      console.log(`$res.result.nModified documents updated successfully.`);
      console.log("Database connection closed.");
      client.close();
    )
    .catch(err => 
      console.log(JSON.stringify(err));
      console.log("Database connection closed.");
      client.close();
    );
);

第 2 步:从终端运行文件:

node C:path\to\your\source_code\user_migration.js

【讨论】:

非常感谢,但是有没有具体的位置可以放第一个解决方案代码?我应该将它永久保存在我的服务器代码中还是只保存一次? 第一个解决方案更像是一次性脚本。所以需要保存。如果您的应用程序正在生产中,则将第二个解决方案放在名为 migration_scripts 的文件夹中,例如在根级别(即,在 index.js/package.json 旁边)并保留它。

以上是关于向架构添加新字段后如何更新旧文档?的主要内容,如果未能解决你的问题,请参考以下文章

使用 mongoose 通过 update 方法向 mongodb 中的现有文档添加新字段

使用 mongoose 通过 update 方法向 mongodb 中的现有文档添加新字段

数据库如何增加字段

Node.js Mongoose 如何保存新文档并向数组字段添加新值

Vapor Fluent 如何向现有表添加新的必填字段键

如何根据旧值更新 rethinkdb 文档中的字段