Reputation: 3863
In my chat application, every user has a dictionary of unread messages which looks like this :
Unread Dictionary
{
_id: // reference to their user_id,
events: [] // array of ObjectIds
}
I want to make a mongoose findByIdAndUpdate query where ) search by ID and $push a new ObjectId into the events array.
If the document doesn't exist, I would like for it to upsert the document assigning it the _id used for the update query and initializing the array with the element being $push ed in the update query.
EDIT:
Here is an example of the query I would like to make:
Model.findByIdAndUpdate(user_id, {$push: {events: event_id}}, {upsert: true}, function (err, updatedDoc) {});
If the document doesn't exist and it decides to upsert, will it use the user_id I used to search to assign the _id on the upserted document? OR will mongo assign it's own _id? I'm looking for something that does the former.
Upvotes: 0
Views: 1711
Reputation: 84
The question is too long, but I hope my answer will help someone. We can use $setOnInsert to specify field only used on insert:
const idUsedOnInsert = new mongoose.Types.ObjectID();
const document = await Model.findByIdAndUpdate(
user_id,
{ $push: { events: event_id }, $setOnInsert: { _id: idUsedOnInsert } },
{ upsert: true }
);
if(document){
console.log('Update');
} else {
console.log('Insert');
}
Upvotes: 1
Reputation: 186
Mongoose will use the _id
you passed as the object _id
when upserting.
You can try that on your console.
Create an ObjectId: const id = ObjectId()
,
then query with <Model>.findByIdAndUpdate(id, { name: 'Albert' }, { upsert: true })
.
And also, if you want to receive the object when it's upsert, you need to pass new: true
within the query options, or else you will receive null
for upserts*
*that's because by default, mongoose/MongoDB returns the find
query's result instead the update
's result, if you'd have queried an update on an existing object, you'd receive the old object in case you didn't pass the new: true
option.
https://docs.mongodb.com/manual/reference/method/db.collection.update/#upsert-option
Upvotes: 0