0

I have tried two different ways to do the same query with Doctrine's MongoDB-ODM.

Can you figure out that why the two, in my opinion similar queries both return different result? Snippet 1 doesn't return anything where Snippet 2 returns correct database entries. Both of the queries seem similar in the log file - except #1 does not have skip & limit lines.

Snippet 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]);

Symfony's log entries from the Snippet 1:

[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": [ ] } [] []

Snippet 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();

Log entries for Snippet 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": [ ] } [] []

My 'user_activity_tracker' service works just as a proxy to the underlying Doctrine repository / document manager. Both snippets get a LoggableCursor back after query.

Ville Mattila
  • 1,343
  • 3
  • 15
  • 28

1 Answers1

0

The extra log output with the query builder method is due to Query::prepareCursor(), which always sets additional cursor options. The repository findBy() method, which utilizes DocumentPersister::loadAll(), only sets options if a non-null value is provided. That explains the difference in log output, but is unrelated to a difference of result sets.

The logged query for each example are identical, apart from a small drift in the ts criteria. If the count() values of both cursors differ, and the results are different after unwrapping the cursor with iterator_to_array(), I would suggest attempting to reproduce this in a failing test case and submit a pull request against the mongodb-odm repository.

jmikola
  • 6,892
  • 1
  • 31
  • 61