【问题标题】:Why wouldn’t mongoDB update the “Date” field of my user entry?为什么 mongoDB 不更新我的用户条目的“日期”字段?
【发布时间】:2021-02-07 09:34:29
【问题描述】:

我在我的 React 应用程序中创建了一个用户模式,如下所示:

const userSchema = new Schema(
{
profileId: String,
expirationDate: { type: Date, default: new Date() },
credits: { type: Number, default: 0 },
},
{ timestamps: { createdAt: "created_at" } }
);

当用户向我付款时,我想通过 post 方法重置/更新两个字段:expirationDate 和 credits。这是我在 expressjs 后端服务器上用于更新 MongoDB Atlas 上的数据库条目的代码:

req.user.expirationDate = new Date(
req.user.expirationDate.setDate(req.user.expirationDate.getDate() + 30)
);
req.user.credits += 1;
const user = await req.user.save();

res.send(user);

一旦操作成功,我可以看到“credits”字段被更新(增加1)。但是,“expirationDate”字段保持不变。更奇怪的是,当我使用“res.send(user)”将更新的用户对象发送到我的前端服务器时,我可以在控制台中看到更新的过期日期。

Successfully updated user model as designed/intended: seen from frontend console

但下面是我在 mongoDB 中看到的:

Updated user entry in MongoDB: the Date field "expirationDate" is not updated; but, the "credits" field is.

这里发生了什么?如何解决?

【问题讨论】:

    标签: node.js reactjs mongodb mongoose


    【解决方案1】:

    我最近遇到了类似的问题,还没有弄清楚这背后的真正原因,但作为一种解决方法,请尝试明确告诉 mongoose expirationDate-field 已更改:

    req.user.expirationDate = new Date(
        req.user.expirationDate.setDate(req.user.expirationDate.getDate() + 30)
    );
    req.user.markModified('expirationDate');
    await req.user.save();
    

    编辑:

    刚刚再次调试它,我认为这种行为背后的原因是您的defaultexpirationDate。尝试将Date.now 函数传递给它,而不是立即将其设置为新日期:

    expirationDate: {type: Date, default: Date.now},
    

    这为我修复了它,而无需使用 markModified()

    【讨论】:

    • 将 new Date() 更改为 Date.now 对我不起作用。但是“解决方法”做到了!我怀疑存在数据类型不匹配,这是导致 MongoDB 不更新的原因。有力的“markModified()”成功了。但它仍然给我留下了为什么......再次感谢您的帮助!
    • 很好,很乐意提供帮助。我可能会再调试一些以找出真正的原因并让你知道:)
    • 好的,所以我已经测试了更多,并且使用Date.now 总是对我有用。可以肯定的是——你没有使用Date.now()(注意括号),对吧?因为如果你这样做了,该字段将设置为Number,因为Date.now() 返回传递的毫秒数。如果您将值设置为实际的Date,猫鼬将不会接受更改,除非我们使用markModified
    • 刚刚再次测试:同样的结果,不工作。经过一些在线研究,我决定将数据类型设为字符串。在后端需要更多的编码行;但它使前端显示更好。目前,我只能摸不着头脑,想知道为什么该解决方案对您有效,但对我无效:数据库、不同版本的节点、猫鼬或其他任何东西......
    【解决方案2】:

    尽管我们仍然有一些未解决的问题,即为什么同一组代码的工作方式不同。我决定暂时不处理它。这是我对原始问题的解决方案:将数据类型从日期更改为字符串。这是一组新的代码:

    在前端创建用户架构:

    const userSchema = new Schema(
      {
        profileId: String,
        expirationDate: { type: String, default: new Date().toDateString() },
        credits: { type: Number, default: 0 },
      },
      { timestamps: { createdAt: "created_at" } }
    );
    

    在后端更新用户到 MongoDB Atlas::

    d = new Date(req.user.expirationDate);
    
    req.user.expirationDate = new Date(
        d.setDate(d.getDate() + 30)
      ).toDateString();
      req.user.credits += 1;
    
    const user = await req.user.save();
    
    console.log(typeof req.user.expirationDate);//Checking the datatype of "expirationDate"
    

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 2017-09-01
      • 2016-11-26
      • 1970-01-01
      • 2019-12-02
      相关资源
      最近更新 更多