You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免重启Node.js服务器时重复创建MongoDB初始5条数据?(基于Mongoose实现)

解决MongoDB重启服务重复插入初始化数据的问题

这问题我之前做项目时也碰到过,每次重启服务就自动重复插数据确实挺烦的!咱们可以从这几个实用的方向来解决:

方法一:先检查再插入(最简单的开发环境方案)

核心思路是:每次加载model时,先检查集合里有没有数据,只有当数据为空的时候才执行插入操作。修改你的main-model.js代码如下:

const mongoose = require('mongoose')
const Schema = mongoose.Schema
const mainSchema = new Schema({
 likes:{
 type:Number,
 max:100000
 },
 people:[{
 key:{type:String},
 name:{type:String}
 }]
},{ timestamps:true })
const MAIN = mongoose.model('liker-model',mainSchema)

// 新增:先检查集合是否为空,再插入初始化数据
MAIN.countDocuments().then(count => {
  if (count === 0) {
    MAIN.insertMany([
      {"_id":mongoose.Types.ObjectId(1),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(2),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(3),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(4),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(5),likes:0,people:[]},
    ])
    .then(() => console.log("初始化数据插入成功"))
    .catch(err => console.error("初始化插入失败:", err))
  }
})

module.exports = MAIN

这个方案的优点是改动小,适合开发阶段快速解决问题;缺点是如果以后你手动删除了某几条数据,重启服务时不会自动补全(只会在全空的时候插入)。

方法二:使用bulkWrite+upsert(确保数据存在且不覆盖现有内容)

如果希望不管集合里有没有数据,都只保留这5条固定ID的文档,且不会覆盖已有的修改内容,可以用MongoDB的批量操作结合upsert(不存在则插入,存在则不做修改):

const mongoose = require('mongoose')
const Schema = mongoose.Schema
const mainSchema = new Schema({
 likes:{
 type:Number,
 max:100000
 },
 people:[{
 key:{type:String},
 name:{type:String}
 }]
},{ timestamps:true })
const MAIN = mongoose.model('liker-model',mainSchema)

// 批量初始化:不存在则插入,存在则跳过
const initDocs = [
  {"_id":mongoose.Types.ObjectId(1),likes:0,people:[]},
  {"_id":mongoose.Types.ObjectId(2),likes:0,people:[]},
  {"_id":mongoose.Types.ObjectId(3),likes:0,people:[]},
  {"_id":mongoose.Types.ObjectId(4),likes:0,people:[]},
  {"_id":mongoose.Types.ObjectId(5),likes:0,people:[]},
]

const bulkOperations = initDocs.map(doc => ({
  updateOne: {
    filter: { _id: doc._id }, // 按ID匹配
    update: { $setOnInsert: doc }, // 只有插入时才设置这些字段
    upsert: true // 不存在就插入,存在则不执行任何操作
  }
}))

MAIN.bulkWrite(bulkOperations)
  .then(result => console.log("初始化完成:", result))
  .catch(err => console.error("初始化出错:", err))

module.exports = MAIN

这个方案更灵活,即使你后续修改了某条文档的likes或people字段,重启服务也不会覆盖这些修改,只会补全缺失的固定ID文档。

方法三:将初始化逻辑移到独立脚本(生产环境推荐)

生产环境下,不建议把初始化逻辑放在model里(万一误操作重复执行会有风险),最好把初始化做成一个独立的脚本,只在需要的时候手动执行:

  1. 新建init-db.js文件:
const mongoose = require('mongoose');
const MAIN = require('./models/main-model'); // 注意路径要对应你的项目结构

// 连接数据库(请替换成你的实际连接字符串)
mongoose.connect('mongodb://localhost:27017/your-db-name')
  .then(async () => {
    console.log("数据库连接成功");
    
    // 先检查是否已经存在数据
    const count = await MAIN.countDocuments();
    if (count > 0) {
      console.log("数据库已有数据,无需初始化");
      process.exit();
    }

    // 执行插入
    await MAIN.insertMany([
      {"_id":mongoose.Types.ObjectId(1),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(2),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(3),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(4),likes:0,people:[]},
      {"_id":mongoose.Types.ObjectId(5),likes:0,people:[]},
    ]);
    
    console.log("初始化数据插入成功");
    process.exit();
  })
  .catch(err => {
    console.error("初始化失败:", err);
    process.exit(1);
  });
  1. 在package.json里添加一个脚本命令:
{
  "scripts": {
    "init-db": "node init-db.js"
  }
}
  1. 需要初始化数据时,在终端执行:
npm run init-db

这个方案最安全,完全避免了重启服务时自动执行插入的问题,适合生产环境使用。


内容的提问来源于stack exchange,提问作者MYTH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:27:37