Доктрина Mongodb ODM и запрос DateTime - PullRequest
4 голосов
/ 23 декабря 2011

Я мог бы помочь с этой проблемой. Я создаю приложение, используя Symfony2 + mongodb + doctrine. Я просто хочу использовать 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") } });

Что я делаю не так? Спасибо за вашу помощь!

Ответы [ 2 ]

9 голосов
/ 14 апреля 2014

Чтобы создать построитель запросов для получения данных, когда date_last_login больше 5 minutes, есть 3 способа

1) создать DateTime объект с вашим форматом даты и времени и затем получить timestamp из DateTime объектасоздать 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) только вcase 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") } });
1 голос
/ 24 декабря 2011

Вероятно, это связано с этой ошибкой PHP, которая была исправлена ​​в 5.3.3:

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

...