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

如何在代码中使用MongoDB UpdateMany方法实现数据更新与新增?

MongoDB定时任务实现数据更新与新增(替代重复插入)

问题描述

原代码会重复向players集合插入数据,需要实现:根据第三方API返回的数据,更新已有数据,同时新增不存在的新数据,而非重复插入。

原代码

cron.schedule('0 0 * * *', async () => {

    const postSchema = new mongoose.Schema({

        id: {
            type: Number,
            required: true
        },
        name: {
            type: String,
            required: true
        },
        status: {
            type: String,
            required: false
        },

    });

    const Post = mongoose.model('players', postSchema);

    async function getPosts() {
        const getPlayers = await fetch("http://localhost:3008/api/players");
        const response = await getPlayers.json();
        for( let i = 0;i < response.players.length; i++){

    const post = new Post({
        id: response.players[i]['id'],
        name: response.players[i]['name'],
        status: response.players[i]['status'],
    });
    post.save();


        }

    }
    console.log("Task submitted successfully")
    await getPosts();
});

用户思路(待修正)

const post = await Post.updateMany({
    id: response.players[i]['id'],
    name: response.players[i]['name'],
    status: response.players[i]['status'],
});

修正方案

核心问题说明

  1. 原代码每次定时任务都重新定义Schema和Model,会导致Mongoose重复注册模型报错,需将Schema/Model定义移到定时任务外部。
  2. updateMany是批量更新匹配的所有文档,不符合单条player的更新/插入需求;应使用updateOne结合upsert: true(存在则更新,不存在则插入),或用bulkWrite批量处理提升性能。

完整修正代码

// 把Schema和Model定义移到定时任务外部,避免重复注册
const postSchema = new mongoose.Schema({
    id: {
        type: Number,
        required: true,
        unique: true // 建议给id加唯一索引,从数据库层面避免重复数据
    },
    name: {
        type: String,
        required: true
    },
    status: {
        type: String,
        required: false
    },
});

const Post = mongoose.model('players', postSchema);

// 定时任务
cron.schedule('0 0 * * *', async () => {
    async function syncPlayers() {
        try {
            const getPlayers = await fetch("http://localhost:3008/api/players");
            const response = await getPlayers.json();
            const players = response.players;

            // 批量处理,比循环逐个操作更高效
            const operations = players.map(player => ({
                updateOne: {
                    filter: { id: player.id }, // 按唯一id匹配文档
                    update: {
                        $set: {
                            name: player.name,
                            status: player.status
                        }
                    },
                    upsert: true // 不存在则插入新文档
                }
            }));

            await Post.bulkWrite(operations);
            console.log("玩家数据同步完成");
        } catch (error) {
            console.error("同步失败:", error);
        }
    }

    await syncPlayers();
});

关键优化点

  • Schema/Model复用:将模型定义移到定时任务外,避免重复注册导致的错误。
  • 唯一索引:给id字段添加unique: true,从数据库层面保证数据唯一性。
  • 批量操作:用bulkWrite批量处理所有玩家数据,减少数据库请求次数,提升性能。
  • Upsert逻辑:通过upsert: true实现"更新已有数据,插入新数据"的需求,替代原有的重复插入。
  • 错误处理:添加try-catch捕获同步过程中的异常,便于排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:21:14