Создайте ObjectID объекта MongoDB с даты в прошлом с помощью драйвера PHP

Мне нужно импортировать большое количество данных в MongoDB из MySQL, и я бы хотел использовать метку времени из ObjectID вместо сохранения ее в отдельном ключе / значении (как в существующих данных). Для этого мне нужно создать ObjectID для существующих данных с датой из прошлого. Мне также нужно сделать это с помощью драйвера PHP. Я читал, что может быть способ сделать это в Python, Java и Node.JS, поэтому я подумал, что, возможно, в PHP существует эквивалентный метод.

Если это возможно – безопасно ли это делать? Смысл, и у меня будут проблемы с дублирующимися или недопустимыми объектами? Благодарю.

В Node.JS:

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

Ниже приведено: MongoDB, используя временные метки для сортировки

В Python:

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

В Java:

 Date d = new Date(some timestamp in ms); ObjectId id = new ObjectId(d) 

Прямо сейчас, драйвер PHP не имеет встроенных функций для этого, __set_state (), о котором упоминается другой ответ только для того, чтобы иметь возможность десериализации идентификатора сеанса и не позволяет создавать его через определенные компоненты.

Для автоматического создания идентификатора вам необходимо сделать следующее:

 <?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() ) ); ?> 

Если вы используете MongoId только для сравнения, например, выбрав все записи в диапазоне дат, вам не нужен полностью действительный идентификатор. Таким образом, вы можете просто сделать:

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

Просто не забудьте никогда не вставлять этот идентификатор и просто использовать его для запросов $ gte / $ gt / $ lt / $ lte.

редактировать

Мой плохой, приведенный выше фрагмент будет работать с датами до 1979 года, так как dechex($timestamp) не всегда возвращает 8 символов, поэтому лучшим фрагментом будет:

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

Это может создать проблемы, поскольку одним из факторов, которые делают уникальным objectid, является временная часть, однако он должен увеличивать последний байт (или так) на нескольких вставках одновременно.

Похоже, что было какое-то движение к тому, чтобы ObjectId был создан с некоторыми параметрами, и он почти так же говорит о нем здесь: http://php.net/manual/en/mongoid.set-state.php

Теоретически, массив свойств, используемых для создания нового идентификатора. Однако, поскольку экземпляры MongoId не имеют свойств, это не используется.

Однако нет никакого способа, я полагаю, что вы достигнете того, что вы можете сделать на других языках, не написав свой собственный генератор ObjectId .