i’m kinda new at develping apps with nodejs and mongoose, i’m trying to update an array of numbers by modifying a single value inside it but i can’t find the correct way to do it.
this is the document:
{
id:5,
arrayOfValues:[2,3,4,5]
}
Let’s say i receive a value of 10 that must be stored in position 1, the desired outcome is:
{
id:5,
arrayOfValues:[2,10,4,5]
}
I thought about using model.findOne()
and then model.updateOne()
but since this operation could be done several times per minute i was searching for a more efficient method.
Edit: This is my current typescript code:
const filter = {'id':receivedMessage.id};
const options = {upsert:true, includeResultMetadata: true};
const foundDocument = await myModel.findOne(filter);
if(foundDocument){
let tempArray = foundDocument.myArray;
let position = receivedMessage.k;
let value = receivedMessage.v
tempArray[position] = value
await myModel.updateOne(filter, {myArray: tempArray}, options);
}
What is the correct way to update only that single element of the array?
2
Answers
You can simplify the update operation by directly using Mongoose updateOne method with the $set operator. Here’s the simplified version of your update operation, without the need to retrieve the document first:
There is no correct way. However, MongoDB recommends the use of its
$push
operator for adding elements to an array. In your case you can leverage a couple of the$push
modifiers to insert your new value at the specified array index with$position
and$each
like so:Notes:
$each
is typicality used to push multiple elements to an array, the$position
modifier can only be used in combination with$each
. The$each
will only have to push in one value toarrayOfValues
which is perfectly fine.Model.findOneAndUpdate
is more efficient than theModel.findOne
+Model.updateOne
given that it performs the update in one database call as opposed to two. It’s also atomic so in theory another client can’t modify the document while you’re updating it withfindOneAndUpdate
. The same isn’t true with afindOne
+updateOne
because Node.js is asynchronous so the event loop handles other requests while it awaits the firstfindOne
call to be resolved/rejected.const doc
will returnnull
if no document was found becauseModel.findOneAndUpdate
either returns the document or returnsnull
(or fails of course).{new:true}
option simply means return the document with the new changes made to it.