使用Symfony 2.1和Doctrine 2对同一实体类型进行多次计数查询

使用Symfony 2.1和Doctrine 2对同一实体类型进行多次计数查询,symfony,count,doctrine,Symfony,Count,Doctrine,对于一个项目,我需要以JSON格式提供大量不同的数据。所有信息都将在同一个页面上使用,因此单个调用将产生最小的开销。这些信息都与同一个数据库对象有关,并且在页面上都是必需的。它基本上是一个计数的集合,它是一个或多个特定类型的对象(这些类型都是布尔型的),我们需要知道很多不同的变化。我使用了下面的代码,但我的同事认为我把它放在JSON列表中的方式有点笨拙,代码可能会有更高的性能。如何改进此代码 public function getContactsStatisticsAction() {

对于一个项目,我需要以JSON格式提供大量不同的数据。所有信息都将在同一个页面上使用,因此单个调用将产生最小的开销。这些信息都与同一个数据库对象有关,并且在页面上都是必需的。它基本上是一个计数的集合,它是一个或多个特定类型的对象(这些类型都是布尔型的),我们需要知道很多不同的变化。我使用了下面的代码,但我的同事认为我把它放在JSON列表中的方式有点笨拙,代码可能会有更高的性能。如何改进此代码

public function getContactsStatisticsAction()
{
    $response = new Response();
    $json = array();
    $em = $this->getDoctrine()->getEntityManager();
    $cr = $em->getRepository('BlaCoreBundle:Company');

    $json['numberOfCompanies'] = $cr->numberOfCompanies();
    $json['numberOfAccounts'] = $cr->numberOfCompanies(array("typeAccount" => true));
    $json['numberOfCompetitors'] = $cr->numberOfCompanies(array("typeCompetitor" => true));
    $json['numberOfSuppliers'] = $cr->numberOfCompanies(array("typeSupplier" => true));
    $json['numberOfOthers'] = $cr->numberOfCompanies(array("typeOther" => true));
    $json['numberOfUnassigned'] = $cr->numberOfCompanies(array("typeAccount" => false, "typeCompetitor" => false,"typeSupplier" => false,"typeOther" => false));

    $json['numberOfJustAccounts'] = $cr->numberOfCompanies(array("typeAccount" => true, "typeCompetitor" => false, "typeSupplier" => false));
    $json['numberOfJustCompetitors'] = $cr->numberOfCompanies(array("typeAccount" => false, "typeCompetitor" => false, "typeSupplier" => false));
    $json['numberOfJustSuppliers'] = $cr->numberOfCompanies(array("typeAccount" => false, "typeCompetitor" => false, "typeSupplier" => false));

    $json['numberOfCompetitorAndAccounts'] = $cr->numberOfCompanies(array("typeAccount" => true, "typeCompetitor" => true, "typeSupplier" => false));
    $json['numberOfCompetitorAndSuppliers'] = $cr->numberOfCompanies(array("typeAccount" => false, "typeCompetitor" => true, "typeSupplier" => true));
    $json['numberOfSupplierAndAccounts'] = $cr->numberOfCompanies(array("typeAccount" => true, "typeCompetitor" => false, "typeSupplier" => true));
    $json['numberOfCompaniesAndAccountsAndSuppliers'] = $cr->numberOfCompanies(array("typeAccount" => true, "typeCompetitor" => true, "typeSupplier" => true));

    $response->setContent(json_encode($json));
    return $response;
}


public function numberOfCompanies($filters = array())
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->select('count(c.id)');
    $qb->from('BlaCoreBundle:Company', 'c');
    $sizeFilters = count ($filters);
    $keys = array_keys($filters);
    if($sizeFilters >= 1){
        $qb->where('c.' . $keys[0] . ' = ' . (int) $filters[$keys[0]]);
    }
    for($i = 1; $i < $sizeFilters; $i++){
        $qb->andWhere('c.' . $keys[$i] . ' = ' . (int) $filters[$keys[$i]]);
    }
    return $qb->getQuery()->getSingleScalarResult();
}
公共函数getContactsStatisticsAction()
{
$response=新响应();
$json=array();
$em=$this->getDoctrine()->getEntityManager();
$cr=$em->getRepository('BlaCoreBundle:Company');
$json['NumberOfCompanys']=$cr->NumberOfCompanys();
$json['numberOfAccounts']=$cr->NumberOfCompanys(数组(“typeAccount”=>true));
$json['numberOfCompetitors']=$cr->numberOfCompanies(数组(“TypeCompetitors”=>true));
$json['numberOfSuppliers']=$cr->NumberOfCompanys(数组(“typeSupplier”=>true));
$json['numberOfOthers']=$cr->NumberOfCompanys(数组(“typeOther”=>true));
$json['numberOfUnassigned']=$cr->NumberOfCompanys(数组(“typeAccount”=>false,“typeCompetitor”=>false,“typeSupplier”=>false,“typeOther”=>false));
$json['numberOfJustAccounts']=$cr->NumberOfCompanys(数组(“typeAccount”=>true,“typeCompetitor”=>false,“typeSupplier”=>false));
$json['numberOfJustCompetitors']=$cr->numberOfCompanies(数组(“typeAccount”=>false,“typeCompetitor”=>false,“typeSupplier”=>false));
$json['numberOfJustSuppliers']=$cr->NumberOfCompanys(数组(“typeAccount”=>false,“typeCompetitor”=>false,“typeSupplier”=>false));
$json['numberOfCompetitorAndAccounts']=$cr->numberOfCompanies(数组(“typeAccount”=>true,“typeCompetitor”=>true,“typeSupplier”=>false));
$json['numberOfCompetitorAndSuppliers']=$cr->numberOfCompanies(数组(“typeAccount”=>false,“typeCompetitor”=>true,“typeSupplier”=>true));
$json['numberOfSupplierAndAccounts']=$cr->NumberOfCompanys(数组(“typeAccount”=>true,“typeCompetitor”=>false,“typeSupplier”=>true));
$json['NumberOfCompanysandAccountsandSuppliers']=$cr->NumberOfCompanys(数组(“typeAccount”=>true,“typeCompetitor”=>true,“typeSupplier”=>true));
$response->setContent(json_encode($json));
返回$response;
}
公共函数numberofcompanys($filters=array())
{
$qb=$this->getEntityManager()->createQueryBuilder();
$qb->选择('count(c.id');
$qb->from('BlaCoreBundle:Company','c');
$sizeFilters=计数($filters);
$keys=数组_键($filters);
如果($sizeFilters>=1){
$qb->where('c...$keys[0].='(int)$filters[$keys[0]]);
}
对于($i=1;$i<$sizeFilters;$i++){
$qb->andWhere('c...$keys[$i].='。(int)$filters[$keys[$i]]);
}
返回$qb->getQuery()->getSingleScalarResult();
}

你的同事是对的。您应该在一个查询中获得所有标量结果。您将以这种方式最小化连接数

这个问题在一个非学说的案例中得到了解决

这样的用户也提出了这个有趣的问题,但没有人回答

实际上,我认为使用QueryBuilderDQL无法解决此类查询。在Doctrine2.2的官方文档中也没有
选择上加入
的示例

您可以尝试以下DQL查询:

return $this->getEntityManager()->createQuery(
  SELECT COUNT(c1) AS C1, COUNT(c2) AS C2, COUNT(c3) AS C3 FROM 
    BlaCoreBundle:Company c1, BlaCoreBundle:Company c2, BlaCoreBundle:Company c3
     WHERE c1.prop1 = 'xxx' AND c2.prop2 > '100' AND c3.prop3 LIKE '%XYZ%')               
  ->getResult();
where子句当然是一般的例子。 此查询将返回一个大小相同的数组,其中C1、C2和C3是您计算的值的键。当然,使用JOIN和您需要的任何东西都会变得困难,但是您可以始终使用
WHERE IN(选择…
WHERE EXISTS(选择…
),例如

  SELECT COUNT(c1) AS C1, COUNT(c2) AS C2, COUNT(c3) AS C3 FROM 
    BlaCoreBundle:Company c1, BlaCoreBundle:Company c2, BlaCoreBundle:Company c3
     WHERE c1.prop1 = 'xxx' AND c2.prop2 > '100' AND c3.prop3 LIKE '%XYZ%'
 AND EXISTS (SELECT x FROM BlaCoreBundle:Entity x JOIN x.company comp WHERE x.prop = "valye" AND comp = c1)               

我想这是属于你的。好吧,我也会把它贴在那里。非常感谢。