Create ObjectID of MongoDB Object from Date in the Past Using PHP Driver

I need to import a large amount of data into MongoDB from MySQL, and I would like to use a timestamp from ObjectID instead of saving it in a separate key / value (as in existing data). To do this, I need to create an ObjectID for existing data with a date from the past. I also need to do this using the PHP driver. I read that there might be a way to do this in Python, Java, and Node.JS, so I thought there might be an equivalent method in PHP.

If possible, is it safe to do? Sense, and I will have problems with duplicate or invalid objects? Thanks.

In Node.JS:

var timestamp = Math.floor(new Date().getTime()/1000); var objectId = new ObjectID(timestamp); 

Below from: MongoDB uses timestamps to sort

In Python:

 gen_time = datetime.datetime(2010, 1, 1) dummy_id = ObjectId.from_datetime(gen_time) 

In Java:

 Date d = new Date(some timestamp in ms); ObjectId id = new ObjectId(d) 
+4
source share
3 answers

Currently, the PHP driver does not have built-in functions for this, __set_state (), which is mentioned by another answer, only in order to be able to deserialize the ID for the session and does not allow creating it through certain components.

To automatically create an identifier, you will need to do the following:

 <?php function createId( $yourTimestamp ) { static $inc = 0; $ts = pack( 'N', $yourTimestamp ); $m = substr( md5( gethostname()), 0, 3 ); $pid = pack( 'n', posix_getpid() ); $trail = substr( pack( 'N', $inc++ ), 1, 3); $bin = sprintf("%s%s%s%s", $ts, $m, $pid, $trail); $id = ''; for ($i = 0; $i < 12; $i++ ) { $id .= sprintf("%02X", ord($bin[$i])); } return new MongoID($id); } var_dump( createId( time() ) ); ?> 
+9
source

If you use MongoId just for comparison, for example, by selecting all entries in a date range, you do not need a fully valid identifier. So you can just do:

 $id = new \MongoId(dechex($timestamp) . str_repeat("0", 16)); 

Just remember to never insert this identifier and just use it for $ gte / $ gt / $ lt / $ lte queries.

change

My bad snippet above will work with dates until 1979, since dechex($timestamp) doesn't always return 8 characters, so the best snippet would be:

 $id = new \MongoId(sprintf("%08x%016x", $timestamp, 0)); 
+7
source

This can create problems, since one of the factors that makes the objectid unique is the temporary part, however it must increase the last byte (or so) on several inserts with the same time.

It seems that there was some movement towards creating an ObjectId with some parameters, and this almost speaks of it here too: http://php.net/manual/en/mongoid.set-state.php

Theoretically, an array of properties used to create a new identifier. However, since MongoId instances have no properties, this is not used.

However, there is no way, I believe that you will achieve what you can do in other languages ​​without writing your own ObjectId generator.

0
source

All Articles