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

如何将Google Calendar API获取的事件批量存入MongoDB并去重验证?

解决Google Calendar事件批量同步到MongoDB的问题

我来帮你搞定把Google Calendar事件批量存到MongoDB的事儿,还能自动基于唯一ID跳过已存在的事件~ 下面是具体的修改步骤和代码:

1. 优化你的EventSchema(可选但推荐)

首先,你的id字段应该设为必填,因为Google返回的每个事件都有唯一ID,这样能避免数据库里出现无ID的无效数据:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const EventSchema = new Schema({
 id: { type: String, required: true, unique:true }, // 把required改为true,确保每个事件都有唯一ID
 start: { type: String },
 end: { type: String },
 status: { type: String },
 creator: { type: Array },
 description: { type: String }
});
module.exports = Event = mongoose.model('events', EventSchema);

2. 修改路由代码,实现批量同步

我们会用Mongoose的bulkWrite方法来做批量操作,效率比循环单个保存高很多,同时通过Google事件的id来判断是否已存在。另外把原来的回调改成async/await,代码更易读:

const Event = require('../models/event'); // 记得引入你的Event模型,路径根据实际项目结构调整
router.post("/google/get", async (req, res, next) => {
  try {
    const { google } = require('googleapis')
    const { addWeeks } = require('date-fns')
    const { OAuth2 } = google.auth
    const oAuth2Client = new OAuth2(
      process.env.GOOGLE_CLIENT_ID,
      process.env.GOOGLE_CLIENT_SECRET
    )
    oAuth2Client.setCredentials({
      refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
    })
    const calendar = google.calendar({ version: 'v3', auth: oAuth2Client })

    // 用await替代回调,获取Google日历事件
    const response = await calendar.events.list({
      calendarId: 'MY CALENDAR ID',
      timeMin: new Date().toISOString(),
      timeMax: addWeeks(new Date(), 1).toISOString(),
      singleEvents: true,
      orderBy: 'startTime',
    });

    const events = response.data.items;
    if (!events.length) {
      console.log("没有找到需要同步的事件");
      return res.status(200).json({ message: "没有需要同步的事件" });
    }

    // 准备批量操作的数组
    const bulkOperations = events.map(event => ({
      updateOne: {
        filter: { id: event.id }, // 用Google事件的唯一ID匹配数据库中的记录
        update: {
          $set: {
            start: event.start.dateTime || event.start.date,
            end: event.end.dateTime || event.end.date,
            status: event.status,
            creator: [event.creator], // Google返回的creator是单个对象,转成数组匹配你的Schema
            description: event.description || '' // 处理description为空的情况
          }
        },
        upsert: true // 关键参数:true=不存在就插入,存在就更新;false=存在就跳过,只新增
      }
    }));

    // 执行批量操作
    const result = await Event.bulkWrite(bulkOperations);

    console.log(`同步完成:新增 ${result.insertedCount} 个事件,更新 ${result.modifiedCount} 个已有事件`);
    res.status(200).json({
      message: "事件同步成功",
      insertedEvents: result.insertedCount,
      updatedEvents: result.modifiedCount
    });

  } catch (err) {
    console.error("同步过程出错:", err);
    res.status(500).json({ error: "事件同步失败", details: err.message });
  }
});

关键细节说明

  • bulkWrite的优势:一次性处理所有事件,减少数据库连接次数,比循环调用save()或findOneAndUpdate()效率高得多,适合批量场景。
  • upsert参数:
    • 如果设为true:数据库中没有该ID的事件就插入新记录,已有则更新字段(适合需要同步最新事件信息的场景)。
    • 如果设为false:只插入不存在的事件,已有事件直接跳过(适合只新增不更新的场景)。
  • 字段映射:确保Google返回的字段和你的Schema对应,比如creator是数组类型,所以把Google返回的单个creator对象包裹成数组。
  • 错误处理:用try/catch捕获所有异步操作的错误,包括Google API调用失败和数据库操作失败,返回清晰的错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:53:11