Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle large doctrine Collections and Associations

I'm working on a project where I have to collect a lot of data from the database. I'm using Symfony2 (symfony bf1281aebdc842a39ec0eb7438e1ea3fca9b9705) and Doctrine2 (doctrine 3b3186ee98392802a44118cd421a3530119aa7eaand ) as working base.

The Problem I encounter is, that I have to fetch about 15.000 articles. After that, I need to iterate through all of them an fetch more data on base of the article id (there are direct and indirect associations with i.e. (inherited) media or prices, etc...). It's ok for about 50-100 records, but if I want to use more records it takes a lot of ram an time to fetch everything from the database.

Is there a way to iterate through the data without using up all of the remaining ram? Is there a way to tell doctrine to stop using references?

Thank you in advance for any help!

like image 654
user969476 Avatar asked Sep 28 '11 16:09

user969476


People also ask

What is a persistent collection in doctrine?

In our entities we work with an array collection but Doctrine uses a persistent collection to lazy load our properties only when required. This is a mechanic of doctrine to improve performance and memory usage. Instead of using a set method, we are going to create methods for adding and removing categories or blog posts to our collections.

Can a blog post have multiple categories in doctrine 2?

This relationship means that a blog post can have multiple categories. And categories can be used in multiple blog posts. As you can see we need a junction table for this. This junction tables links the blog posts with the correct categories. So how is the simplest and most correct way to do this in Doctrine 2 with entities?

Why can’t I return arraycollection in doctrine?

If you try to return ArrayCollection then you will get the following error: So why is this? Well if we look deeper in the Doctrine classes we can find the following: Collection is an interface and we should use that instead. Use your interfaces and not your implementations!

What is a unidirectional many-to-many Association?

From Doctrine's point of view, it is simply mapped as a unidirectional many-to-many whereby a unique constraint on one of the join columns enforces the one-to-many cardinality. The following example sets up such a unidirectional one-to-many association:


2 Answers

save another line by using:

$iterableResult = $doctrine->getManager()->createQuery("SELECT c FROM ENTITY c")->iterate();

while ((list($obj) = $iterableResult->next()) !== false) {
    // do something with $obj
    $em->detach($obj);
}
like image 147
user2815640 Avatar answered Sep 21 '22 18:09

user2815640


You can look into using iterative (step-by-step) hydration in Doctrine:

$em = $this->getDoctrine()->getEntityManager();
$q  = $em->createQuery("<DQL to select the objects I want>");
$iterableResult = $q->iterate();
while (($row = $iterableResult->next()) !== false) {
    // do stuff with the data in the row, $row[0] is always the object
    $em->detach($row[0]); // detach from Doctrine, so that it can be GC'd immediately
}

Details from this article, under Mass object processing

like image 26
Jrgns Avatar answered Sep 18 '22 18:09

Jrgns