我计划使用Mongo ObjectID来比较时间戳,即:
$fourteenDaysAgo = time() - (14 * 86400);
$lookFor = array(
'_id' => $user
);
$updateFields = array(
'$pull' => array(
'Rewards' => array(
'_id' => array(
'$lt' => new MongoId(dechex($fourteenDaysAgo).'0000000000000000')
)
),
),
);
$returnFields = array(
'_id' => 1,
);
$userData = $db->users->findAndModify($lookFor, $updateFields, $returnFields);
令我烦恼的是这个具体的
new MongoId(dechex($fourteenDaysAgo).'0000000000000000')
与其他图书馆C#或Py相比,这有一种令人不安的" hackish"感觉呢:
ObjectId.from_datetime( fourteen_days_ago )
我一直在查看文档,但似乎无法找到PHP的等价物......它不存在吗?有没有更好的办法?即那些不会让我离开的东西" wtf是我在这里做的?"当我最终在N个月后重新访问这个剧本时?
答案 0 :(得分:0)
我绝对同意这有点hackish,但它并不像看起来那么糟糕。但要理解,让我们来看看what an ObjectID is made out of。它们是12个字节,用24个字节的十六进制表示
通过添加12个零,它会消除构成普通哈希的其余数据。考虑到机器标识符,进程ID和随机计数器是为了防止将相同的ID插入到DB中两次,伪造该数据以进行比较的行为并不是那么糟糕。所有查询都在使用前4个字节。
这种仅dechex
时间戳的方法也有可能返回少于8个字节的十六进制,这将导致Mongo丢弃哈希并立即创建一个新哈希值。 (或者,最近,致命错误)我建议:
$timestamp = str_pad(dechex($timestamp), 8, '0', STR_PAD_LEFT);
仔细观察,我们可以看看actual Mongo PHP extension,,我们可以模仿创建过程。如果你需要一个ID,那么它最终会在数据库中结束,我只需要创建一个新ID并换掉前8个十六进制字符:
$id = new MongoId($timestamp.substr(new MongoID(), 8));