1
votes

I currently have an upsert function in my project which works but my main problem is that it creates another instance of the record, and updates the new instance instead. This is the code:

router.route('/carousel/update/:_id').put(function(req, res) {

 var id;
 if(req.params._id  == 'undefined'){

    id = crypto.randomBytes(12).toString('hex');
 } 

 else {
    id = ObjectId(req.params._id)
 }

 db.collection('home').updateOne({"_id": id},
     {$set: req.body}, {upsert: true}, (err, results) => {
         if (err) throw err;
         res.send(results)

         console.log(req.body)
 });
});

The problem:

1. It mystifies me that mongoDB takes my crypto generated _id and takes it as the new _id for the upserted document. Why is that? When {upsert: true}, isn't mongoDB supposed to generate a new _id?

2. Because of the nature of problem 1, whenever I try to update the original document, it updates the upserted document instead since they have the same _id values even though their _ids are positioned at different document levels.

In conclusion, when given a 'home' document, how do I upsert correctly without adding a new record with the same values and _ids?

Thanks for your help!

EDIT

This is the JSON body content of the document with custom generated _id using crypto:

{
    "_id": "1262d480eea83567181b3206",
    "header": "hello",
    "subheader": "hello"
}

Whereas, this is the body content of the upserted document.

{
    "_id": {
        "$oid": "1262d480eea83567181b3206"
    },
    "header": "helloasad",
    "subheader": "helloasda"
}

As observed, after upserting, it takes the same _id value of the original document but on another document level.

1
Can you share the body content? - Ashwanth Madhav
I'll add it in my question! - Brio Tech
@AshwanthMadhav I've edited my question, please feel free to look through it again :) - Brio Tech
check if id is objectId. If not use updateOne({"_id": ObjectId(id)} - Ashwanth Madhav
@AshwanthMadhav Hey there! Your solution worked! If you would be so kind to provide an answer and explain it, I would be more than happy to accept it as the verified/accepted answer. Thanks a lot! - Brio Tech

1 Answers

0
votes

A possible solution/explanation based on @Ashwanth Madhav information:

In your code 'id' was being sent to the update as a String type, but the id in MongoDB is an ObjectId type:

Code will be something like that:

var id;
 if(req.params._id  == 'undefined'){
    // 'id' NEED TO BE AN ObjectId...
    // 'id' WAS BEING SENT AS A 'String'
    id = ObjectId(crypto.randomBytes(12).toString('hex'));
 } 

 else {
    id = ObjectId(req.params._id)
 }