Petr Peller
Petr Peller

Reputation: 8826

Doctrine2 - limit returned associated entities

Is it possible to limit how many associations will be returned from DB? For example lets say I have following entities:

/** @Entity */
Article {
   /** @OneToMany(targetEntity="Comments") */
   private $comments; 
   ...
}

/** @Entity */
Comments { ... }

And when iterating over collection of articles I would like to get just 5 recent comments. (there could be 100 or more in total). I fetch the collection from a custom repository using QueryBuilder.

In practice I would use something like this:

$articles = $em->getRepository("Article")->findArticles($commentLimit, ...);
foreach($articles as $article) {
   foreach($article->getComments() as $comment) {
       //loop will iterate just $commentLimit times
       echo $comment->getText();
   }
}

Is it possible to do this within a signle query?

Upvotes: 1

Views: 341

Answers (1)

Ocramius
Ocramius

Reputation: 25431

In this particular case I would use

/** @Entity */
Article {
   /**
    * @OneToMany(targetEntity="Comments", fetch="EXTRA_LAZY")
    * @OrderBy({"lastModified" = "DESC"})
    */
   private $comments; 
}

@OrderBy just sorts the fetched elements by one or more attributes in this case by their last modified date. Using EXTRA_LAZY on collections changes their behavior, as some of the methods won't initialize the entire collection, but just some pieces of it. It is the case of Doctrine\ORM\PersistentCollection#slice($start, $end), which you could use in your example to just load the first elements:

$articles = $em->getRepository("Article")->findArticles(...);
foreach($articles as $article) {
   foreach($article->getComments()->slice(0, $commentLimit) as $comment) {
       echo $comment->getText();
   }
}

If what you want to do is fetch the last 5 comments regardless of the article, then you should use DQL.

Upvotes: 2

Related Questions