我正在尝试使用findOneAndUpdate
和$set
更新一个文档,但我显然错过了一些非常重要的东西,因为新的请求正在覆盖旧的值。
我的Device
模式是这样的:
{
deviceId: {
type: String,
immutable: true,
required: true,
},
version: {
type: String,
required: true,
},
deviceStatus: {
sensors: [
{
sensorId: {
type: String,
enum: ['value1', 'value2', 'value3'],
},
status: { type: Number, min: -1, max: 2 },
},
],
},
}
我正在尝试使用这段代码来更新文档:
const deviceId = req.params.deviceId;
Device.findOneAndUpdate(
{ deviceId },
{ $set: req.body },
{},
(err, docs) => {
if (err) {
res.send(err);
} else {
res.send({ success: true });
}
}
);
当我尝试从邮递员发送一个包含一个或多个传感器的请求时,只有最后一个请求被保存在数据库中。
{
"deviceStatus": {
"sensors": [
{
"sensorId": "test",
"status": 1
}
]
}
}
我希望能够更新基于req.body
的数据库中已经存在的值,或者在需要时添加新的值。如有任何帮助,不胜感激。
文件说:
$set操作符用指定的值替换字段的值价值。
您需要$push操作符,它将指定的值附加到数组中。
拥有这些文档:
[
{
_id: 1,
"array": [
2,
4,
6
]
},
{
_id: 2,
"array": [
1,
3,
5
]
}
]
使用$set operator:
db.collection.update({
_id: 1
},
{
$set: {
array: 10
}
})
结果:
{
"_id": 1,
"array": 10
}
使用$push操作符:
db.collection.update({
_id: 1
},
{
$push: {
array: 10
}
})
结果:
{
"_id": 1,
"array": [
2,
4,
6,
10
]
}
你想在一个findOneAndUpdate中使用$push
和$set
,这是不可能的,我更喜欢使用findById()
和process
和save()
,所以请尝试
let result = await Device.findById(deviceId )
//implementation business logic on result
await result.save()
如果你想在每次发出请求时推送新的传感器,那么更新你的代码,如下所示:
const deviceId = req.params.deviceId;
Device.findOneAndUpdate(
{ deviceId },
{
$push: {
"deviceStatus.sensors": { $each: req.body.sensors }
}
},
{},
(err, docs) => {
if (err) {
res.send(err);
} else {
res.send({ success: true });
}
}
);
更新到旧答案:
如果你想在每次发出请求时更新传感器,那么更新你的代码,如下所示:
const deviceId = req.params.deviceId;
Device.findOneAndUpdate(
{ "deviceId": deviceId },
{ "deviceStatus": req.body.sensors },
{ upsert: true },
(err, docs) => {
if (err) {
res.send(err);
} else {
res.send({ success: true });
}
}
);