求助:Mongoose无法更新带时间戳的布尔对象,直接赋值无时间戳更新
我看到你遇到的问题主要来自两个地方:Schema结构的错误定义,以及更新操作没有正确触发时间戳更新。咱们一步步来解决:
1. 修正你的Schema定义
首先看你原来的Schema,waterMotor.state的写法是错误的——你把time字段嵌套在了state的属性里,但Mongoose中,当你给字段指定type后,其他属性是该字段的配置选项(比如default),而不是子字段。正确的结构应该是waterMotor包含两个独立字段:state(布尔型)和time(日期型),像这样:
const mongoose = require('mongoose'); const PlantProductSchema = new mongoose.Schema({ waterMotor: { state: { type: Boolean, default: false }, time: { type: Date, default: Date.now } }, }); module.exports = mongoose.model('PlantProduct', PlantProductSchema);
这样定义后,waterMotor是一个子文档,包含state和time两个字段,符合Mongoose的Schema规范。
2. 正确更新字段并同步时间戳
现在有几种方式可以实现更新state的同时更新time:
方法一:使用文档实例的set方法+save,手动更新时间戳
如果你已经获取了plantProduct文档实例,可以这样做:
plantProduct.waterMotor.state = idResultsObj.motorState; plantProduct.waterMotor.time = Date.now(); // 手动设置当前时间 await plantProduct.save(); // 保存更改
方法二:使用Mongoose预保存钩子(自动更新时间戳)
如果希望每次waterMotor.state变化时自动更新time,可以给Schema添加pre('save')钩子:
const PlantProductSchema = new mongoose.Schema({ waterMotor: { state: { type: Boolean, default: false }, time: { type: Date, default: Date.now } }, }); // 添加预保存钩子 PlantProductSchema.pre('save', function(next) { // 只有当waterMotor.state发生变化时,才更新time if (this.isModified('waterMotor.state')) { this.waterMotor.time = Date.now(); } next(); }); module.exports = mongoose.model('PlantProduct', PlantProductSchema);
这样之后,你只需要像之前一样直接赋值state然后save,time就会自动更新了:
plantProduct.waterMotor.state = idResultsObj.motorState; await plantProduct.save();
方法三:使用Model的updateOne方法直接更新(适合不需要先获取文档的场景)
如果你不想先获取文档实例,可以直接用Model的更新方法,同时设置state和time:
await PlantProduct.updateOne( { _id: plantProductId }, // 你的查询条件 { $set: { 'waterMotor.state': idResultsObj.motorState, 'waterMotor.time': Date.now() } } );
为什么你原来的更新操作报错?
你之前用plantProduct.waterMotor.update({state: idResultsObj.motorState })报错,是因为waterMotor是文档实例的一个子对象,它没有update方法——update是Model或者Query对象的方法,不是子文档的方法。修正Schema后,用上面的方法就可以正常更新了。
内容的提问来源于stack exchange,提问作者yaron k

