4

我可以在这个问题上使用一些帮助。我正在使用 Symfony2 + mongodb + 教义创建一个应用程序。我只想使用 Doctrine ODM 查询最近 5 分钟内登录的所有用户。我有一个用户集合,其中包含一个名为 date_last_login 的日期字段。

所以我尝试像这样使用查询构建器:

<?php
// Creating a DateTime object and susbtract 5 min from now
// local time is 15:40:05, timezone: 'Europe/Paris'
$_dateTime = new \DateTime();
$_interval5Min = new \DateInterval('PT5M');
$_dateTime->sub($_interval5Min);

$query = $this->createQueryBuilder('User')
                ->field('date_last_login')->gte($_dateTime)
                ->getQuery();
                ->execute();

当我使用 symfony2 探查器查看组装查询时,我得到了以下结果:

db.User.find({ "date_last_login": { "$gte": new Date("Fri, 23 Dec 2011 15:30:05 +0100") } });

除了日期早 10 分钟而不是 5 分钟之外,这似乎很好?我只是不明白。如果我转储我的 php DateTime 对象,日期是正确的:2011-12-23 15:35:05(15:40 前五分钟)。

因此,我尝试在不减去任何分钟数的情况下组装相同的查询,这一次,一切都很好:

<?php
// local time is 15:50:00
$query = $this->createQueryBuilder('User')
            ->field('date_last_login')->gte(new \DateTime())
            ->getQuery();
            ->execute();

// query is ok:
db.User.find({ "date_last_login": { "$gte": new Date("Fri, 23 Dec 2011 15:50:00 +0100") } });

我究竟做错了什么 ?谢谢您的帮助!

4

2 回答 2

9

创建查询构建器以获取数据时date_last_login5 minutes有 3 种方式更好

1)DateTime使用您的日期时间格式创建对象并timestampDateTime对象获取然后创建MongoDate对象:

$timeBefore5MinutesAgo  = new \DateTime(date('Y-m-d H:i:s',\time() - 5 * 60));
$mongoDateBefore5MinutesAgo = new \MongoDate($currentDateWithTime->getTimestamp());

$query = $this->createQueryBuilder('User')
    ->field('date_last_login')->gte($mongoDateBefore5MinutesAgo)
    ->getQuery();
    ->execute();

2)创建MongoDate对象并使用 strtotime 将您的日期时间格式转换为timestamp

$mongoDateBefore5MinutesAgo = new \MongoDate(strtotime(date('Y-m-d H:i:s',\time() - 5 * 60)));

$query = $this->createQueryBuilder('User')
    ->field('date_last_login')->gte($mongoDateBefore5MinutesAgo)
    ->getQuery();
    ->execute();

3)只有在这种情况下Doctrine 2 ODM,您才能DateTime使用您的日期时间格式创建对象:

$timeBefore5MinutesAgo  = new \DateTime(date('Y-m-d H:i:s',\time() - 5 * 60));

$query = $this->createQueryBuilder('User')
              ->field('date_last_login')->gte($timeBefore5MinutesAgo)
              ->getQuery();
              ->execute();

所有 3 种方式都将创建查询:

db.User.find({ "date_last_login": { "$gte": new ISODate("2014-03-15T19:35:08+02:00") } });
于 2014-04-14T18:44:18.490 回答
1

这可能是由于在 5.3.3 中修复的这个 PHP 错误:

https://bugs.php.net/bug.php?id=50916

于 2011-12-24T05:42:16.110 回答