使用PHP驱动程序从过去的日期创建MongoDB对象ID
我必须从MySQL将大量数据导入MongoDB,我希望使用ObjectID中的时间戳,而不是将其存储在单独的键/值中(就像在现有数据中一样)。为了做到这一点,我需要为现有数据创建一个ObjectID,日期来自过去。我还需要使用PHP驱动程序来实现这一点。我已经读到,在Python、Java和Node.JS中可能有一种方法可以做到这一点,所以我认为在PHP中可能有一种等效的方法 如果这是可能的-这样做安全吗?我和Means在重复或无效objectid方面会有问题吗?谢谢 在Node.JS中:使用PHP驱动程序从过去的日期创建MongoDB对象ID,php,mongodb,Php,Mongodb,我必须从MySQL将大量数据导入MongoDB,我希望使用ObjectID中的时间戳,而不是将其存储在单独的键/值中(就像在现有数据中一样)。为了做到这一点,我需要为现有数据创建一个ObjectID,日期来自过去。我还需要使用PHP驱动程序来实现这一点。我已经读到,在Python、Java和Node.JS中可能有一种方法可以做到这一点,所以我认为在PHP中可能有一种等效的方法 如果这是可能的-这样做安全吗?我和Means在重复或无效objectid方面会有问题吗?谢谢 在Node.JS中: va
var timestamp = Math.floor(new Date().getTime()/1000);
var objectId = new ObjectID(timestamp);
以下资料来自:
在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)
这可能会产生问题,因为使objectid唯一的因素之一是时间部分,但是它应该在同一时间增加多个插入的最后一个字节(大约) 看起来有一种趋势是允许使用一些参数创建ObjectId,事实上,这里几乎谈到了它: 理论上,用于创建新id的属性数组。但是,由于MongoId实例没有属性,因此不使用该数组
然而,atm,我相信如果不编写自己的
ObjectId
generator,就无法实现其他语言中的功能。现在,PHP驱动程序没有内置的功能,即u set\u state()提到的另一个答案仅用于会话反序列化ID,不允许通过特定组件创建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() ) );
?>
如果您使用MongoId只是为了比较,例如,选择日期范围内的所有记录,则不需要完全有效的id。因此,您可以简单地执行以下操作:
$id = new \MongoId(dechex($timestamp) . str_repeat("0", 16));
请确保永远不要插入此id,而只将其用于$gte/$gt/$lt/$lte查询
编辑
我的缺点是,上面的代码段可以处理1979年以前的日期,因为dechex($timestamp)
并不总是返回8个字符,所以更好的代码段应该是:
$id = new \MongoId(sprintf("%08x%016x", $timestamp, 0));
如果我在按时间戳升序的循环中执行这些插入,我可以编辑此函数以传入$lastTimestamp值并更改以下内容:静态$inc=0;如果($lastTimestamp>0&&$lastTimestamp!=$yourtimstamp)$inc=0;它似乎对我有用,但我只是想检查一下这个没有问题。user1114701,是的,应该可以,但你不应该这样做$inc应该总是递增的,而不是每个时间戳都有。