Hi, need help on writing some proper aggregation for change stream
I am getting data some thing like
{
"_id": {
"$oid": "6285ee2b91c6e50012a76e0b"
},
"status": "new",
"lastUpdatedData": {
"timestamp": {
"$date": {
"$numberLong": "1670602175000"
}
},
"priority": 0,
"gps": {
"longitude": 0,
"latitude": 0,
"altitude": 0,
"angle": 0,
"satellites": 0,
"speed": 0
},
"event_id": 0,
"properties_count": 8,
"ioElements": [
{
"id": 239,
"label": "Ignition",
"value": 0,
"valueHuman": "Ignition Off",
"valueDB": 0,
"_id": {
"$oid": "63935e17ac1fa5b006927e26"
}
},
{
"id": 240,
"label": "Movement",
"value": 0,
"valueHuman": "Movement Off",
"valueDB": 0,
"_id": {
"$oid": "63935e17ac1fa5b006927e27"
}
},
{
"id": 200,
"label": "Sleep Mode",
"value": 2,
"valueHuman": "Deep Sleep",
"valueDB": 2,
"_id": {
"$oid": "63935e17ac1fa5b006927e28"
}
},
{
"id": 67,
"label": "Battery Voltage",
"value": 3791,
"valueHuman": "3.791 V",
"valueDB": 3.791,
"_id": {
"$oid": "63935e17ac1fa5b006927e2b"
}
},
{
"id": 68,
"label": "Battery Current",
"value": 0,
"valueHuman": "0 A",
"valueDB": 0,
"_id": {
"$oid": "63935e17ac1fa5b006927e2c"
}
}
]
},
"category": "companyCar"
}
- My first question is regarding updating the ‘ioElements’ array and I want to update
{
"id": 239,
"label": "Ignition",
"value": 0,
"valueHuman": "Ignition Off",
"valueDB": 0,
}
to
{
"id": 239,
"label": "Ignition",
"value": 1,
"valueHuman": "Ignition On",
"valueDB": 1
}
I want to perform a kind of upsert on ioElements array i.e update the existing fields with new fields if any new object is present inside ioElements I receive I need to push to ioElements array how to achieve this in an effective way. My current implementation
ioElements.forEach(async (singleIoEle) => {
const ioElementExist = await Vehicle.findOne({
_id: mongoose.Types.ObjectId(vehicleId),
"lastUpdatedData.ioElements.id": singleIoEle.id,
});
if (ioElementExist) {
await Vehicle.updateMany(
{
_id: mongoose.Types.ObjectId(vehicleId),
"lastUpdatedData.ioElements.id": singleIoEle.id,
},
{
$set: {
"lastUpdatedData.ioElements.$": {
...singleIoEle,
},
},
}
);
} else {
await Vehicle.findByIdAndUpdate(
mongoose.Types.ObjectId(vehicleId),
{
$addToSet: { "lastUpdatedData.ioElements": { ...singleIoEle } },
}
);
}
}),
Can the above code be improved and perform update in effective way?
- We also have a change stream opened to show updates on latest values on frontend my change stream aggregation pipeline
const ids = Array.of(ObjectId(...vehicleIds));
const pipeline = [
{
$match: {
operationType: 'update',
'documentKey._id': { $in: ids }
},
},
];
Now issue is this pipeline is triggered on each of ioElement is updated which is creating load on servers. I want to get update only once when my updating code has finished(get update not everytime a single ioElement is update rather get update only one after all the single ioElements are written)