【问题标题】:Why Doctrine2 ODM's results of findBy() and createQueryBuilder()->getQuery()->execute() differ from each other?为什么 Doctrine2 ODM 的 findBy() 和 createQueryBuilder()->getQuery()->execute() 结果不一样?
【发布时间】:2012-08-14 02:53:02
【问题描述】:

我尝试了两种不同的方法来使用 Doctrine 的 MongoDB-ODM 执行相同的查询。

你能弄清楚为什么这两个在我看来相似的查询都返回不同的结果吗? Snippet 1 不返回 Snippet 2 返回正确数据库条目的任何内容。这两个查询在日志文件中看起来很相似 - 除了 #1 没有跳过和限制行。

片段 1

$dateDayAgo = new \DateTime('1 day ago');
$recentLogins = $this->get('user_activity_tracker')->findBy(array(
      'targetUser' => $userAccount->getId(),
      'code' => array('$in' => array('login.attempt','login.ok')),
      'ts' => array('$gte', $dateDayAgo)
    ))->sort(['ts' => 1]);

来自 Snippet 1 的 Symfony 日志条目:

[2012-08-13 09:14:33] doctrine.INFO: MongoDB query: { "find": true, "query": { "targetUser": ObjectId("4fa377e06803fa7303000002"), "code": { "$in": [ "login.attempt", "login.ok" ] }, "ts": [ "$gte", new Date("Sun, 12 Aug 2012 09:14:33 +0000") ] }, "fields": [ ], "db": "eventio_com", "collection": "ActivityEvent" } [] []
[2012-08-13 09:14:33] doctrine.INFO: MongoDB query: { "sort": true, "sortFields": { "ts": 1 }, "query": { "targetUser": ObjectId("4fa377e06803fa7303000002"), "code": { "$in": [ "login.attempt", "login.ok" ] }, "ts": [ "$gte", new Date("Sun, 12 Aug 2012 09:14:33 +0000") ] }, "fields": [ ] } [] []

片段 2

$recentLoginsQuery = $this->get('user_activity_tracker')->createQueryBuilder()
        ->field('targetUser')->equals($userAccount->getId())
        ->field('code')->in(array('login.attempt','login.ok'))
        ->field('ts')->gte($dateDayAgo)
        ->sort('ts','asc')
        ->getQuery();

$recentLogins = $recentLoginsQuery->execute();

片段 2 的日志条目:

[2012-08-13 09:17:30] doctrine.INFO: MongoDB query: { "find": true, "query": { "targetUser": ObjectId("4fa377e06803fa7303000002"), "code": { "$in": [ "login.attempt", "login.ok" ] }, "ts": { "$gte": new Date("Sun, 12 Aug 2012 09:17:30 +0000") } }, "fields": [ ], "db": "eventio_com", "collection": "ActivityEvent" } [] []
[2012-08-13 09:17:30] doctrine.INFO: MongoDB query: { "limit": true, "limitNum": null, "query": { "targetUser": ObjectId("4fa377e06803fa7303000002"), "code": { "$in": [ "login.attempt", "login.ok" ] }, "ts": { "$gte": new Date("Sun, 12 Aug 2012 09:17:30 +0000") } }, "fields": [ ] } [] []
[2012-08-13 09:17:30] doctrine.INFO: MongoDB query: { "skip": true, "skipNum": null, "query": { "targetUser": ObjectId("4fa377e06803fa7303000002"), "code": { "$in": [ "login.attempt", "login.ok" ] }, "ts": { "$gte": new Date("Sun, 12 Aug 2012 09:17:30 +0000") } }, "fields": [ ] } [] []
[2012-08-13 09:17:30] doctrine.INFO: MongoDB query: { "sort": true, "sortFields": { "ts": 1 }, "query": { "targetUser": ObjectId("4fa377e06803fa7303000002"), "code": { "$in": [ "login.attempt", "login.ok" ] }, "ts": { "$gte": new Date("Sun, 12 Aug 2012 09:17:30 +0000") } }, "fields": [ ] } [] []

我的“user_activity_tracker”服务只是作为底层 Doctrine 存储库/文档管理器的代理。两个 sn-ps 在查询后都会返回一个 LoggableCursor。

【问题讨论】:

    标签: mongodb symfony doctrine-orm doctrine-odm


    【解决方案1】:

    查询构建器方法的额外日志输出是由于Query::prepareCursor(),它总是设置额外的游标选项。使用DocumentPersister::loadAll() 的存储库findBy() 方法仅在提供非空值时设置选项。这解释了日志输出的差异,但与结果集的差异无关。

    每个示例的记录查询都是相同的,除了ts 标准中的小偏差。如果两个游标的count() 值不同,并且使用iterator_to_array() 解开游标后结果不同,我建议尝试在失败的测试用例中重现这一点,并针对mongodb-odm 存储库提交拉取请求。

    【讨论】:

    • 再次感谢您,我稍后会再次讨论这个问题。
    猜你喜欢
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多