2016-04-26 9 views
0

複雑なクエリのヘルプが必要です。 サーバーはクエリ用のいくつかのパラメータを受け取ります。そのクエリはjsonにシリアル化されています。私は各クエストの平均評価を追加する必要があります(フィールドはjson.item [i] .ratingからアクセス可能なので)、評価で並べ替えます。Doctrine querybuilder複合ルール

さらにもう1つ:平均的なレーティングをdbに保つより良い方法はありますか?私は常に評価を計算することは良い考えではないと感じています。

PS:btwスイッチがヌルチェックの方が速いですか?

//some params 

$repository = $this->getDoctrine()->getRepository('AppBundle:Quest'); 
     $qb = $repository->createQueryBuilder('q') 
      ->innerJoin('q.city', 'c') 
      ->where('c.id = :city_id') 
      ->setParameter('city_id', $cityId); 

     if($minPlayers != null){ 
      $qb ->andWhere('q.minplayers >= :minplayers') 
       ->setParameter('minplayers', $minPlayers); 
     } 
     if($maxPlayers != null){ 
      $qb ->andWhere('q.maxplayers <= :maxplayers') 
       ->setParameter('maxplayers', $maxPlayers); 
     } 
     if($tagsId != null){ 
      $qb ->innerJoin('q.tags','t') 
       ->andWhere('t.id IN (:tags)') 
       ->setParameter(':tags', implode(",", $tagsId)); 
     } 
     if($organizerId != null){ 
      $qb ->andWhere('q.organizer = :organizer_id') 
       ->setParameter('organizer_id', $organizerId); 
     } 
     if($ispremium != null){ 
      $qb ->andWhere('q.ispremium = :isPremium') 
       ->setParameter('isPremium', $ispremium) 
       ->addOrderBy('q.premiumorder', 'ASC'); 
     } 
     $qb ->setFirstResult($FirstResult) 
      ->setMaxResults($MaxResults); 


     $query = $qb->getQuery(); 

     $paginator = new Paginator($query, $fetchJoinCollection = true); 
     $c = count($paginator); 

     $result = $query->getResult(); 

     $serializer = $this->get('jms_serializer'); 
     $data = $serializer->serialize($result, 'json', 
      SerializationContext::create() 
       ->enableMaxDepthChecks() 
       ->setGroups(array('questSearch')) 
     ); 

     $json ='{"total_count":'.$c.',"items":'.$data.',"amountOfelems":'.$amountOfelems.',"citySlug":'.json_encode($citySlug).',"userId":'.json_encode($userId).'}'; 

     return new JsonResponse($json); 

エンティティ:

class Quest{ 
... 
/** 

    * @OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="quest") 
    */ 
    protected $comments; 
} 



class Comments{ 
/** 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 
/** 
    * @ORM\Column(type="integer") 
    */ 
    protected $rating; 
/** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Quest", inversedBy="comments") 
    * @ORM\JoinColumn(name="quest_id", referencedColumnName="id") 
    */ 
    protected $quest; 
} 

答えて

1

(また、全体的なパフォーマンスのための最善の方法)最も簡単な方法は、クエストテーブルであなたのQuestの評価を保存し、それをCommentがあるたびにリフレッシュすることです編集/追加。そのためにDoctrine Eventsを使用することができます。

これは、あなたが各リクエストで計算する必要がなく、クエストテーブルをリクエストするときに自動的にレーティングが選択されるため、両方の問題を解決します。