2013-10-02 61 views
0

我的數據庫中有大約60k的文檔,我無法查詢它們。我能夠成功檢索它們的唯一方法是使用水合物(假)選項。基本教條MongoDB拋出的內存不足異常

我曾經嘗試都:

$dm = $this->get('doctrine_mongodb')->getManager(); 
    $qb = $dm->createQueryBuilder('BConwayWebsiteBundle:Business') 
     ->eagerCursor(true); 
    $query = $qb->getQuery(); 
    $results = $query->execute(); 

$dm = $this->get('doctrine_mongodb')->getManager(); 
    $qb = $dm->createQueryBuilder('BConwayWebsiteBundle:Business'); 
    $query = $qb->getQuery(); 
    $results = $query->execute(); 

如果我傾倒$結果>將IsInitialized()它是假的。我相信那是因爲在那時我還沒有使用它。儘管我試圖做的任何訪問都會導致內存問題。甚至像$ results-> count()一樣基本。

[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"find":true,"query":[],"fields":[],"db":"ClosedForTheHoliday","collection":"businesses"} [] [] 
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"limit":true,"limitNum":null,"query":[],"fields":[]} [] [] 
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"skip":true,"skipNum":null,"query":[],"fields":[]} [] [] 
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"sort":true,"sortFields":[],"query":[],"fields":[]} [] [] 
[2013-10-01 23:54:56] emergency.EMERGENCY: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) {"type":1,"file":"/media/sf_sites/cfth_com/vendor/doctrine/mongodb/lib/Doctrine/MongoDB/Cursor.php","line":237} [] 

更新:如果我限制我的結果到2000年,它的工作原理。此外,如果我在查詢後只選擇兩個字段,我可以將其限制爲15000並取得成功。當我將其限制爲2000時,dev調試欄顯示查詢使用了120MB的內存。我需要能夠遍歷所有結果,並且不能分頁。這似乎應該是可能的,而不必100MB +查詢...

回答

0

我只需要由兩場不同的數據,所以這是我落得這樣做:

$dm = $this->get('doctrine_mongodb')->getManager(); 

// Get organization name from all businesses (distinct) 
$organizations = $dm->createQueryBuilder('BConwayWebsiteBundle:Business') 
    ->distinct('organization') 
    ->getQuery() 
    ->toArray(); 

// Get business name from all businesses (distinct) 
$names = $dm->createQueryBuilder('BConwayWebsiteBundle:Business') 
    ->field('organization')->equals('') 
    ->field('organization')->equals(null) 
    ->distinct('name') 
    ->getQuery() 
    ->toArray(); 

// Create new array from results of both queries 
$businesses = array_merge($organizations, $names); 

// Filter out any null or empty values 
$businesses = array_filter($businesses, function($item) { 
    return (!is_null($item) && strlen($item) > 0); 
}); 

// Filter out any duplicates 
array_unique($businesses); 

// Sort array case-insensitive 
sort($businesses, SORT_STRING | SORT_FLAG_CASE); 
0

因爲MongoDB的學說是ODM持久管理器(同樣適用於關係數據庫的Doctrine ORM 2.x),對水合對象的引用將被內部存儲,並且不會被PHP的垃圾回收所恢復,就像您正在迭代非水合數組結果並快速離開作用域一樣。

對於Doctrine中的任何批處理操作,您都需要定期clear()所有託管對象的對象管理器,或者手動detach()單個對象。定期的clear()可能會對你來說最簡單,因爲你可以在結果中每X次迭代一次。您可以在this blog post中找到一些代碼示例和對此解決方案的討論。雖然它是從ORM及其EntityManager類的角度編寫的,但ODM的DocumentManager通過Doctrine Common庫實現了相同的ObjectManager接口,您可以在其中找到detach()clear()方法。