我可以更新:deviceName、macAddress 和 blacklisted,但连接对象中的任何值都不会更新(即:active、connectionURL 和配置)。 if 语句的目的是在用户将它们留空时不修改数据库中的值。
架构:
const deviceSchema = new Schema({
deviceName: { type: String, required: true, trim: true },
macAddress: { type: String, required: true, unique: true, trim: true },
blacklisted: {type: Boolean, required: true},
connection: { type: Object, required: true,
active: { type: Boolean, required: true, trim: true },
connectionUrl: { type: String, required: true, trim: true},
configuration: { type: String, required: true, trim: true},
},
}, {
timestamps: true,
});
更新数据库:
router.route('/update/config/:id').post((req, res) => {
Device.findById(req.params.id)
.then(device => {
device.macAddress = req.body.macAddress;
device.connection.active = req.body.active;
if (req.body.connectionUrl != '' && req.body.connectionUrl != "Choose...") {
device.connection.connectionUrl = req.body.connectionUrl;
}
if (req.body.configuration != '') {
device.connection.configuration = req.body.configuration;
}
device.save()
.then(() => res.json('device configuration(s) updated!'))
.catch(err => res.status(400).json('Error: ' + err));
})
.catch(err => res.status(400).json('Error: ' + err));
});
最佳答案
在 Mongoose 中,如果您为模式分配“对象”类型,它将变为 Mixed架构,这意味着几件事,但在您的情况下最重要的是 Mongoose 无法自动检测对文档该部分的更改。
您在这里寻找的可能是“嵌套路径”或“子文档”。参见 here有关两者之间差异的更多信息。
要点是,您需要更改定义架构的方式。这里有几个选项:
1。您确切地知道连接对象有哪些成员,并且总是希望能够分配给它们,即使您从未明确创建过连接也是如此。
在这种情况下,最好的选择是“嵌套路径”,其定义如下:
const deviceSchema = new Schema({
deviceName: { type: String, required: true, trim: true },
macAddress: { type: String, required: true, unique: true, trim: true },
blacklisted: {type: Boolean, required: true},
connection: {
active: { type: Boolean, required: true, trim: true },
connectionUrl: { type: String, required: true, trim: true},
configuration: { type: String, required: true, trim: true},
},
}, {
timestamps: true,
});
2。您确切地知道连接对象有哪些成员,但只希望在整个连接已经创建的情况下能够分配给特定成员。
在这种情况下,您将要使用子文档
const connectionSchema = new Schema({
active: { type: Boolean, required: true, trim: true },
connectionUrl: { type: String, required: true, trim: true },
configuration: { type: String, required: true, trim: true },
}, { timestamps: false });
const deviceSchema = new Schema({
deviceName: { type: String, required: true, trim: true },
macAddress: { type: String, required: true, unique: true, trim: true },
blacklisted: {type: Boolean, required: true},
connection: { type: connectionSchema, required: true },
}, {
timestamps: true,
});
编辑:引用下面评论中发布的问题:如果您希望能够从多个“deviceSchema”引用相同的 connectionSchema,您需要更改为以下内容这个:
const deviceSchema = new Schema({
deviceName: { type: String, required: true, trim: true },
macAddress: { type: String, required: true, unique: true, trim: true },
blacklisted: {type: Boolean, required: true},
connection: { type: Schema.Types.ObjectId, required: true, ref: "Connection" },
}, {
timestamps: true,
});
在这种情况下,您还需要确定您正在显式创建两个模型(一个设备模型和一个连接模型),并确保加载连接模型设备模型,然后您将运行:
DeviceModel.findOne(/*whatever*/).populate('connection')
而不是普通的“查找”方法。不过,这与最初的问题有点相去甚远。
3。你不知道连接对象的确切结构
在这里,您可以使用 built in 'Mixed' type和你一样,但它伴随着一个警告,你不能定义任何更多的 child , Mongoose 不会自动检测文档那部分的变化,这意味着 device.save()
赢了'自动更新连接对象中的任何内容。
const deviceSchema = new Schema({
deviceName: { type: String, required: true, trim: true },
macAddress: { type: String, required: true, unique: true, trim: true },
blacklisted: {type: Boolean, required: true},
connection: { type: Object, required: true },
}, {
timestamps: true,
});
为了告诉 mongoose 连接字段已经更新,我们必须在 device.save()
关于mongodb - 如何使用 React 和 axios 更新 MongoDB 中文档的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67184580/