猫鼬只更新请求体中可用的字段



我正在尝试使用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()processsave(),所以请尝试

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 });
}
}
);

最新更新