我必须从MySQL导入大量数据到MongoDB中,我想使用ObjectID中的时间戳,而不是将其存储在单独的键/值中(就像在现有数据中一样).为了做到这一点,我需要为现有数据创建一个ObjectID,其中包含过去的日期.我还需要使用PHP驱动程序执行此操作.我已经读过在Python,Java和Node.JS中可能有一种方法可以做到这一点,所以我想也许在PHP中有一个等效的方法.
如果可能的话 - 这样做是否安全?意思是我会遇到重复或无效的ObjectID问题?谢谢.
在Node.JS中:
var timestamp = Math.floor(new Date().getTime()/1000);
var objectId = new ObjectID(timestamp);
Run Code Online (Sandbox Code Playgroud)
下面是:MongoDB使用时间戳进行排序
在Python中:
gen_time = datetime.datetime(2010, 1, 1)
dummy_id = ObjectId.from_datetime(gen_time)
Run Code Online (Sandbox Code Playgroud)
在Java中:
Date d = new Date(some timestamp in ms);
ObjectId id = new ObjectId(d)
Run Code Online (Sandbox Code Playgroud)
Der*_*ick 11
现在,PHP驱动程序没有内置的功能,__ set_state(),另一个答案提到的只是能够对ID进行会话反序列化,并且不允许您通过特定组件创建它.
您必须执行以下操作才能自动创建ID:
<?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() ) );
?>
Run Code Online (Sandbox Code Playgroud)
如果您仅使用MongoId进行比较,例如,选择日期范围内的所有记录,则不需要完全有效的ID.所以你可以这样做:
$id = new \MongoId(dechex($timestamp) . str_repeat("0", 16));
Run Code Online (Sandbox Code Playgroud)
请务必不要插入此ID,只需将其用于$ gte/$ gt/$ lt/$ lte查询.
编辑
我的不好,上面的片段可以在大约1979年之前使用日期,因为dechex($timestamp)
并不总是返回8个字符,所以更好的片段是:
$id = new \MongoId(sprintf("%08x%016x", $timestamp, 0));
Run Code Online (Sandbox Code Playgroud)