5

プロジェクトでは、JSON 形式でさまざまなデータをロードする必要があります。すべての情報が同じページで使用されるため、1 回の呼び出しでオーバーヘッドが最小限に抑えられます。情報はすべて同じデータベース オブジェクトに関係し、ページ上ですべて必要です。これは基本的に、特定のタイプ (タイプはすべてブール値) の 1 つ以上のオブジェクトの数のコレクションであり、これのさまざまなバリエーションを知る必要があります。私は以下のコードを使用しましたが、私の同僚は、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();
}
4

1 に答える 1

3

あなたの同僚は正しいです。単一のクエリですべてのスカラー結果を取得する必要があります。この方法で接続数を最小限に抑えます。

このトピックは、Doctrine 以外のケースのこの回答で解決されます。

このようなユーザーは、ここでも興味深い質問をしましたが、答えはありませんでした。

実際、この種のクエリをQueryBuilderDQLで解決する方法はないと思います。また、 Doctrine2.2の公式ドキュメントには、 aJOIN上の aの例はありませんSELECT

試すことができるのは、次の 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 を持つ 1 つのサイズの配列を返します。もちろん、 JOIN と必要なものを使用することは難しくなりますが、いつでもWHERE IN (SELECT...)andWHERE EXISTS (SELECT...)を使用できます。

  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)               
于 2013-01-12T14:37:34.717 に答える