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

Mongoose同Schema跨集合复制用户文档仅存默认值问题排查

问题原因

查询返回的user是Mongoose Document类实例,不是原生JavaScript对象。直接用展开运算符...展开时,只能获取到实例上的可枚举自有属性,无法拿到数据库查询返回的实际业务字段值,最终传给DeletedUser构造函数的有效字段为空,落库后就只会保留Schema中定义的默认值。

另外原代码还有两个不规范点:

  • 调用Model构造函数生成实例是同步操作,前面加await没有任何作用
  • save()是异步写入操作,未加await会存在写入未完成就执行后续逻辑、无法捕获写入异常的问题
解决方法

两种方案二选一即可:

  • 方法1:查询时调用.lean(),直接返回原生JS对象
    加了.lean()后,查询返回的结果不再是Mongoose Document实例,就是普通对象,展开时可以正常拿到所有字段:
    const user = await User.findOne({ _id: id }).lean();
    if (user) {
      // 如果不需要复用原用户_id,可放开下一行注释,让Mongo自动生成新_id
      // delete user._id;
      const deletedUser = new DeletedUser({
        ...user,
      });
      await deletedUser.save();
    }
    
  • 方法2:对Document实例调用.toObject()转为普通对象
    如果查询后还需要用到Mongoose Document的内置方法,可以查询出实例后,调用自带的toObject()方法转成普通对象再展开:
    const user = await User.findOne({ _id: id });
    if (user) {
      const userData = user.toObject();
      // 如果不需要复用原用户_id、版本号字段,可放开下两行注释
      // delete userData._id;
      // delete userData.__v;
      const deletedUser = new DeletedUser({
        ...userData,
      });
      await deletedUser.save();
    }
    

补充说明:两个集合Schema完全一致的场景下,以上两种写法都可以保证写入deleted-users集合的数据和原users集合数据完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:31:12