119

I use NodeJS to insert documents in MongoDB. Using collection.insert I can insert a document into database like in this code:

// ...
collection.insert(objectToInsert, function(err){
   if (err) return;
   // Object inserted successfully.
   var objectId; // = ???
});
// ...

How can I get the _id of inserted object?

Is there any way to get the _id without getting latest object inserted _id?

Supposing that in same time a lot of people access the database, I can't be sure that the latest id is the id of object inserted.

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474

12 Answers12

100

A shorter way than using second parameter for the callback of collection.insert would be using objectToInsert._id that returns the _id (inside of the callback function, supposing it was a successful operation).

The Mongo driver for NodeJS appends the _id field to the original object reference, so it's easy to get the inserted id using the original object:

collection.insert(objectToInsert, function(err){
   if (err) return;
   // Object inserted successfully.
   var objectId = objectToInsert._id; // this will return the id of object inserted
});
Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
  • 4
    Very insightful thank you. Couldn't find this information anywhere else since the change in callback parameters. – Brad Hein Jul 26 '15 at 18:39
  • @BradHein You're welcome! Probably the MongoDB driver modifies the object reference, so it gets modified here too. :) – Ionică Bizău Jul 27 '15 at 04:25
  • Your code is wrong, where you say var objectId = objectToInsert._id; you meant to say var objectId = objectInserted._id; – Andy Lorenz Jul 28 '15 at 13:48
  • 3
    @AndyLorenz What is `objectInserted`? I guess you're missing exactly the point of this answer: the Mongo driver appends the `_id` field to the original object. I edited the answer to use `objectToInsert` everywhere. Hope the things are clearer now. :) – Ionică Bizău Jul 28 '15 at 18:50
  • Well you have edited your reference to "objectInserted" out of your answer, I was only commenting on your own mistake. The point you say I have missed is exactly what your answer should make explicit - and therefore I have submitted an edit of your answer for peer review (so that it spells out very clearly how to achieve a solution in this way). regards – Andy Lorenz Jul 29 '15 at 08:07
  • @AndyLorenz I saw your edit suggestion -- this is not a Meteor behavior but it's done by MongoDB driver (I guess!). Cheers! `:-)` – Ionică Bizău Jul 29 '15 at 09:25
  • whoops, if I'd said Meteor then I of course meant Mongo ! But I see you've edited your answer again and yes it looks much more useful now - and so I've upvoted it :) – Andy Lorenz Jul 29 '15 at 14:43
  • @AndyLorenz Yeah... Everybody loves upvotes. I gave you some as well. :) – Ionică Bizău Jul 29 '15 at 15:36
  • 3
    NOTE: `insert()` is deprecated. Use `insertOne()` instead – evilReiko Nov 24 '16 at 12:07
  • @evilReiko Interesting. Source? – Ionică Bizău Nov 25 '16 at 08:31
  • @IonicăBizău I can't seem to find it in the official documentation, but at least that's what my IDE told me, also, I found this which seems to enhance that: http://stackoverflow.com/a/36794912/134824 – evilReiko Nov 25 '16 at 13:47
  • To get the inserted ID as a string use objectId.toString() – TreeAndLeaf Nov 01 '18 at 06:00
92

There is a second parameter for the callback for collection.insert that will return the doc or docs inserted, which should have _ids.

Try:

collection.insert(objectToInsert, function(err,docsInserted){
    console.log(docsInserted);
});

and check the console to see what I mean.

georgedyer
  • 2,737
  • 1
  • 21
  • 25
  • 4
    Callback actually returns array of documents inserted. So, if you have inserted a single document then you can access the inserted record as below. collection.insert({name:"David", title:"About MongoDB"}, function(err, records){ console.log("Record added as "+records[0]._id); }); Ref: http://mongodb.github.io/node-mongodb-native/markdown-docs/insert.html – Rohit Singh Sengar Jun 16 '14 at 11:47
  • 2
    The Callbacks API has changed: http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#~WriteOpResult – tenbits May 13 '15 at 13:10
  • link does not lead anywhere useful – davidhadas Apr 08 '16 at 21:42
  • I don't know if this is general or only works in meteor, but when you call collection.insert(object), it returns the id of the inserted object right away. – vantesllar Oct 30 '16 at 20:45
  • 4
    docsInserted does not return an _id for me. it returns for me { "ok": 1, "n": 1, "opTime": { "ts": "6361004504208375809", "t": 5 }, "electionId": "7fffffff0000000000000005" } – user1709076 Dec 06 '16 at 15:08
  • @davidhadas - I removed the link - runnable was sold to Mulesoft and they took down their product – georgedyer Mar 01 '18 at 17:17
  • ✅ In my case, the right answer was this one: https://stackoverflow.com/a/54204838/6195123 Just getting the element with await [operation], then like this `result.insertedId.toString()`, and done ✅ – Jean Manzo Aug 27 '21 at 12:23
22

As ktretyak said, to get inserted document's ID best way is to use insertedId property on result object. In my case result._id didn't work so I had to use following:

db.collection("collection-name")
  .insertOne(document)
  .then(result => {
    console.log(result.insertedId);
  })
  .catch(err => {
    // handle error
  });

It's the same thing if you use callbacks.

Serjuice
  • 569
  • 4
  • 16
13

if you want to take "_id" use simpley

result.insertedId.toString() 

// toString will convert from hex

Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35
  • 1
    That's what i was looking for. Thank you. – Fadwa Sep 21 '19 at 12:55
  • 2
    Yea, there must have been a version change since the other answers don't mention `result.insertedId` is an `ObjectID` type object. `.toString()` will convert this object into a real UUID. – Dylan Pierce Jul 09 '20 at 00:27
12

I actually did a console.log() for the second parameter in the callback function for insert. There is actually a lot of information returned apart from the inserted object itself. So the code below explains how you can access it's id.

collection.insert(objToInsert, function (err, result){
    if(err)console.log(err);
    else {
        console.log(result["ops"][0]["_id"]);
        // The above statement will output the id of the 
        // inserted object
       }
});
Sidak
  • 187
  • 1
  • 10
  • 2
    This outputs an `ObjectID {_bsontype: "ObjectID", id: Buffer(12)}`. How can i use it to get the actual id that is in the database?... Found the answer in another comment: Use `result.insertedId.toString() ` – Fadwa Sep 21 '19 at 12:54
8

Mongo sends the complete document as a callbackobject so you can simply get it from there only.

for example

collection.save(function(err,room){
  var newRoomId = room._id;
  });
Saurabh Chandra Patel
  • 12,712
  • 6
  • 88
  • 78
8

You could use async functions to get _id field automatically without manipulating data object:

async function save() {
  const data = {
    name: "John"
  }

  await db.collection('users').insertOne(data)

  return data
}

Returns (data object):

{
    _id: '5dbff150b407cc129ab571ca',
    name: 'John',
}

kuzey beytar
  • 3,076
  • 6
  • 37
  • 46
6

Now you can use insertOne method and in promise's result.insertedId

ktretyak
  • 27,251
  • 11
  • 40
  • 63
  • Could you provide a code example? Where does this result object come from? – JSideris Sep 20 '16 at 22:00
  • @JSideris, as you can see in the specification method [insertOne()](http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#insertOne), this method accepts three parameters `(doc, options, callback)`. The third parameter - a callback, [which takes two parameters](http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#~insertOneWriteOpCallback) `(error, result)`. And `result` - this is what you are looking for. – ktretyak Sep 21 '16 at 00:10
2

@JSideris, sample code for getting insertedId.

db.collection(COLLECTION).insertOne(data, (err, result) => {
    if (err) 
      return err;
    else 
      return result.insertedId;
  });
Pyae Sone
  • 1,574
  • 2
  • 14
  • 18
1

Similar to other responses, you can grab the variable using async await, es6+ features.

const insertData = async (data) => {

  const { ops } = await db.collection('collection').insertOne(data)
  console.log(ops[0]._id)
  
}
Stephen Romero
  • 2,812
  • 4
  • 25
  • 48
0

Another way to do it in async function :

const express = require('express')
const path = require('path')
const db = require(path.join(__dirname, '../database/config')).db;
const router = express.Router()

// Create.R.U.D
router.post('/new-order', async function (req, res, next) {

    // security check
    if (Object.keys(req.body).length === 0) {
        res.status(404).send({
            msg: "Error",
            code: 404
        });
        return;
    }

    try {

        // operations
        let orderNumber = await db.collection('orders').countDocuments()
        let number = orderNumber + 1
        let order = {
            number: number,
            customer: req.body.customer,
            products: req.body.products,
            totalProducts: req.body.totalProducts,
            totalCost: req.body.totalCost,
            type: req.body.type,
            time: req.body.time,
            date: req.body.date,
            timeStamp: Date.now(),

        }

        if (req.body.direction) {
            order.direction = req.body.direction
        }

        if (req.body.specialRequests) {
            order.specialRequests = req.body.specialRequests
        }

        // Here newOrder will store some informations in result of this process.
        // You can find the inserted id and some informations there too.
        
        let newOrder = await db.collection('orders').insertOne({...order})

        if (newOrder) {

            // MARK: Server response
            res.status(201).send({
                msg: `Order N°${number} created : id[${newOrder.insertedId}]`,
                code: 201
            });

        } else {

            // MARK: Server response
            res.status(404).send({
                msg: `Order N°${number} not created`,
                code: 404
            });

        }

    } catch (e) {
        print(e)
        return
    }

})

// C.Read.U.D


// C.R.Update.D


// C.R.U.Delete



module.exports = router;
Yohan W. Dunon
  • 502
  • 10
  • 18
0

you can use this in Javascript :

  let insert = await messageDB.insertOne({
  });
  console.log(insert.insertedId);

sooo easy!