Mongoose to define update-upsert does insert or update

I want to test if the "upsert" option for the update is woking fine. This way I "increment" the object twice in mongodb with the same key. However, it did not show the inserted message. Am I missing something?

(mongodb: v2.6.3; mongoose: 3.8.15)

Member.findOneAndRemove({user_id : 1},
    function (err, doc) {
        if (!err) onsole.log(doc ? 'deleted' : 'not found');
}); // -> deleted, make sure user_id = 1 doesn't exist

Member.update({user_id : 1}, 
    {$set : {name:"name1"}}, 
    {upsert : true, new : false}, // new : false, so that I can detect original doc is null then know it a new one.
    function (err, doc) {
    if (!err) {
        console.log(doc ? 'updated' : 'inserted')
    }
}); // -> updated ? But it shoule be inserted, right ?

Member.update({user_id : 1}, 
    {$set : {name:"name2"}}, 
    {upsert : true, new : false},
    function (err, doc) {
    if (!err) {
        console.log(doc ? 'updated' : 'inserted')
    }
}); // -> updated, yes, no problem.

      

Thanks for any hint.

============ Answer =============

Use . findOneAndUpdate instead of .update! Also, make sure the option is: {upsert: true, new: false } so that the second parameter (doc) of the callback can be the original document in the case.

+3


source to share


1 answer


Method .update()

in mongoose takes three argument to the callback: err

, numAffected

and a raw

response. Use the "raw" object to find out what happened:

Member.update({user_id : 1}, 
    {$set : {name:"name1"}}, 
    {upsert : true }, 
    function (err, numAffected, raw) {
    if (!err) {
        console.log(raw)
    }
});

      

You will see a structure like this:

{ ok: true,
  n: 1,
  updatedExisting: false,
  upserted: [ { index: 0, _id: 5456fc7738209001a6b5e1be } ] }

      

Therefore, the values n

and "updatedExisting keys available, where the second is false on upserts and true otherwise.

upserted will contain the

_id" of any new documents are always created .

As far as n

or "numAffected" is concerned, it is basically always 1 where the document is matched against legacy-related responses.

You can see the new WriteResult response in MongoDB 2.6 and up using the Bulk Operations form:



var bulk = Member.collection.initializeOrderedBulkOp();
bulk.find({user_id : 1}.upsert().update({$set : {name:"name1"}});
bulk.execute(err,result) {
   console.log( JSON.stringify( result, undefined, 2 ) );
}

      

On the first iteration, you will get something like this:

{
  "ok": 1,
  "writeErrors": [],
  "writeConcernErrors": [],
  "nInserted": 0,
  "nUpserted": 1,
  "nMatched": 0,
  "nModified": 0,
  "nRemoved": 0,
  "upserted": [
    {
      "index": 0,
      "_id": "5456fff138209001a6b5e1c0"
    }
  ]
}

      

And the second one with the same parameters like this:

{
  "ok": 1,
  "writeErrors": [],
  "writeConcernErrors": [],
  "nInserted": 0,
  "nUpserted": 0,
  "nMatched": 1,
  "nModified": 0,
  "nRemoved": 0,
  "upserted": []
}

      

And the document will be marked as "modified" where something was actually changed.

So anyway, the operations .update()

don't return the modified document or the original document. This is a method .findOneAndUpdate()

, a mongoose wrapper around the main one .findAndModify()

, that performs an atomic operation. Methods .update()

are generally for bulk operations and, as such, do not return document content.

+5


source







All Articles