35

Creating a document:

$db->collection->insert($content);
// $newDocID = ???

I'm trying to get the new document's id. How? Thanks.

Mark
  • 32,293
  • 33
  • 107
  • 137

4 Answers4

62

According to the docs the array you pass to insert will be amended with an _id field:

$db->collection->insert($content);
$newDocID = $content['_id'];
Theo
  • 131,503
  • 21
  • 160
  • 205
  • 11
    If you __need__ the ID after the insert before you do another operation, you might also look at adding the `fsync` option: `$db->collection->insert($content, 'fsync' => \TRUE);` This ensures the "transaction" is completed first... – ZagNut Apr 02 '12 at 19:07
  • 1
    Please note that this answer if for old legacy mongo driver. If you are looking for an answer for the new driver check this: http://stackoverflow.com/a/37834261/352959 – King Julien Mar 01 '17 at 16:30
34

You can also get _id before insert. Just add _id field to document with new MongoId ie.

$content['_id'] = new MongoId();
$db->collection->insert($content);

Also there are nice benefits of this:

  1. You don't need fsync flag like posted in comment by ZagNut in previous answer. So you don't need to wait for reply from DB.
  2. You don't need to actually insert anything to DB to get id. So you can prepare some related objects and then insert or not insert them - somewhat like transactions which mongo does not support (yet?).
  3. You actually can generate id in your application, not in db, So you can do whatever you want before or after insert.
  • Disadvantage: This can have error `E11000 duplicate key error index`, if at same moment this function called from different clients. – Somnath Muluk Aug 03 '15 at 11:42
  • @SomnathMuluk from my understanding, this is basically impossible. Every mongo id is a combination of timestamp, machine hostname and an incremental counter. If all clients have a unique hostname, how is this supposed to happen? – alapeno Sep 02 '15 at 18:22
  • @alapeno Why would you assume you wouldn't have multiple clients on the same hostname? Although, based on the docs, the ID not only is based on the host, but the process, timestamp & an incremental counter, so even if the hostname is the same, and the timestamp is the same, the process & incremental counter parts should differ, so I'm also wondering how you would get the duplicate key error? The PHP docs state that the ID will be unique, so if there is collisions, that is a bug in PHP I would think. – Josh Ribakoff Sep 03 '15 at 01:52
  • @alapeno : I thought in same way. But I have received this error multiple times (1-2 times in week) when there are about 10k connections per minute. – Somnath Muluk Sep 03 '15 at 05:18
  • @JoshRibakoff sorry, I forget to mention the process id (or rather the hash of it) – alapeno Sep 03 '15 at 09:55
  • @SomnathMuluk That's strange, how many processes / hosts are used in your setup? – alapeno Sep 03 '15 at 09:56
24

This works for me:

$insertResult = $collection->insertOne($object);
$id = $insertResult->getInsertedId();
the_root
  • 329
  • 3
  • 9
1
 $newDocument = $db->collection->findAndModify ( $row, $row, null, array('new'=>true,'upsert' => true));
 $strId = $newDocument['_id']->{'$id'};

http://php.net/manual/en/mongocollection.findandmodify.php

BbopLifa
  • 131
  • 2
  • 5
  • 1
    Recommending a findAndModify() w/ upsert & new flags sounds like it would work if running Mongo >= 3.x.x, but its an over complicated & less portable way to simply insert & get the ID, when insert() already does it. – Josh Ribakoff Sep 03 '15 at 01:57