我的数据库中有大约60k文档,我无法查询它们。我能够成功检索它们的唯一方法是使用hydrate(false)选项。
我试过了两个:
$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();
如果我转储$ results-> isInitialized(),则为false。我相信那是因为我还没有利用它。我尝试做的任何访问都会导致内存问题。甚至像$ 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 :(得分: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);
答案 1 :(得分:0)
由于Doctrine MongoDB ODM是一个持久性管理器(对于关系数据库也是Doctrine ORM 2.x),对水合对象的引用存储在内部,并且不会被PHP的垃圾收集恢复,就像你在迭代非水合阵列的结果很快就会留下范围。
对于Doctrine中的任何批处理操作,您需要定期clear()
所有托管对象的对象管理器,或手动detach()
单个对象。在您的情况下,定期clear()
可能是最简单的,因为您可以在结果中每X次迭代执行一次。您可以在this blog post中找到一些代码示例和对此解决方案的讨论。虽然它是从ORM及其EntityManager类的角度编写的,但ODM的DocumentManager从Doctrine Common库实现了相同的ObjectManager接口,您可以在其中找到detach()
和clear()
方法。