4

is there any way to get the record _id after an upsert?

I've seen this post (How to insert a doc into mongodb using mongoose and get the generated id?), but this is oriented only to inserts, not updates.

Also, using the MongoDB you can use get the _id using getlasterror (https://groups.google.com/forum/?fromgroups=#!topic/mongoose-orm/ehZ11QY-OUw), but Mongoose doesn't provides access to it (https://groups.google.com/forum/?fromgroups=#!topic/mongoose-orm/pSv6WrasvWg)

Thanks

Community
  • 1
  • 1
AkerbeltZ
  • 569
  • 1
  • 8
  • 13

3 Answers3

11

Use Mongoose's findOneAndUpdate method with upsert: true in the options object.

var query = { name: 'borne' },
    data = { name: 'jason borne' },
    options = { upsert: true };
Model.findOneAndUpdate(query, data, options, function (err, object) {
    /* use object._id */
});
Tom Ashworth
  • 2,415
  • 1
  • 21
  • 22
  • 4
    Note that if you want the *updated* document returned, and in cases where it didn't exist and was upserted the *new* document, you will want to add new: true to the options: options = { upsert: true, new: true }; – JamieL Jun 09 '15 at 16:40
1

If you want the updated document returned, and in cases where it didn't exist and was upserted the new document. Below is the option you need to set.

set new: true to the options: options = { upsert: true, new: true };

Source: Based on Jamiel's comment, I am adding his comment as an answer as it was hard time finding for me to get that _id when no document existed and created by upsert (And I was trying to create my own extended method).

Anonymous Creator
  • 2,968
  • 7
  • 31
  • 77
0

Another possibility with promises:

Model.findOneAndUpdate(query, data, options, function (err, object) {
})).then((result) => {
    /* return result.upserted[0]._id */
})

...where result is the following:

{ n: 1,
  nModified: 0,
  upserted: [ { index: 0, _id: /* some id */ } ],
  ok: 1 }
solo
  • 743
  • 2
  • 6
  • 17