I am building an App and I have a problem inside a for loop.
Inside my function I got two arrays as arguments (payload.data.start and payload.data.end) and I am trying to push it inside the mongodb. My code looks like this
async function emplaceAval (state, payload, blockInfo, context) {
for(var i=0 ; i<payload.data.start.length ; i++) // start and end have the same length
{
const user =await User.findOne({ 'account': payload.data.account })
user.availability.push({start: new Date(payload.data.start[i]+'Z') , end: new Date(payload.data.end[i]+'Z')});
await user.save();
}
}
The problem is that lots of times I lose data. By losing data I mean that the i changes before user.save take place.
I consider to use forEach , but I have two arrays that need to be save together , so I cant .
The second solution I thought is to create an index array . For example if the length of my arrays is 5 , I will create an indexTable=[0 , 1 , 2 , 3 , 4 ] and I will use asyncForEach to this array. But i dont think that this solution is the preferable. Any ideas? Thanks in advance
From what I can see here the looping is completely unneccesary. MongoDB has a $push
operator which allows update of an array without retrieving the document first. This also has an $each
option to allow a list of elements to be "pushed" in the singe update.
In short this is just one request and response to the server to await
:
// Transpose to array of objects for update
let availability = payload.data.start.map((e,i) =>
({ start: new Date(e+'Z'), end: new Date(payload.data.end[i] + 'Z') })
);
try {
// Perform the **one** update request
let response = await User.updateOne(
{ 'account': payload.data.account },
{ '$push': { 'availability': { '$each': availability } } }
);
// maybe check the response
} catch(e) {
// do something with any error
}
That's all you need do. No need to "loop" and so much less overhead than going back and forth to the server retrieving a document and making changes then putting the document back.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.