4

私はこの問題についていくらかの助けを使うことができました。Symfony2 + mongodb+doctrineを使用してアプリケーションを作成しています。Doctrine ODMを使用して、過去5分間にログインしたすべてのユーザーにクエリを実行したいだけです。date_last_loginという日付フィールドを持つUserコレクションがあります。

だから私はそのようなクエリビルダーを使おうとします:

<?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") } });

日付が5分ではなく10分早いことを除けば問題ないようです。わからない。php DateTimeオブジェクトをダンプした場合、日付は正しいです:2011-12-23 15:35:05(15:40の5分前)。

そこで、分を差し引くことなく同じクエリを組み立てようとしましたが、今回はすべて問題ありません。

<?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

3つの方法date_last_loginよりも優れている場合にデータを取得するためのクエリビルダーを作成するには5 minutes

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)場合に限り、日時形式でオブジェクトを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 に答える