2014-09-29 2 views
0

Профайлер показывает этот запрос:Как я могу изменить построитель запросов доктрины?

SELECT 
    count(DISTINCT c0_.id) AS sclr0 
FROM 
    customers c0_ 
    LEFT JOIN customers_addresses c1_ ON c0_.id = c1_.customer_id 
    LEFT JOIN customers_phones c2_ ON c0_.id = c2_.customer_id 
WHERE 
(
    c0_.is_lead = ? 
    AND c0_.firstname LIKE ? 
) 
    OR c0_.lastname LIKE ? 
    OR c0_.email LIKE ? 
    OR c0_.company LIKE ? 
    OR c1_.street_address1 LIKE ? 
    OR c1_.street_address2 LIKE ? 
    OR c1_.city LIKE ? 
    OR c1_.state = ? 
    OR c1_.zipcode = ? 
    OR c2_.phone LIKE ? 

И явно не то, что я хочу, я хочу, чтобы это было так:

SELECT 
    count(DISTINCT c0_.id) AS sclr0 
FROM 
    customers c0_ 
    LEFT JOIN customers_addresses c1_ ON c0_.id = c1_.customer_id 
    LEFT JOIN customers_phones c2_ ON c0_.id = c2_.customer_id 
WHERE 
(
    c0_.is_lead = ? 

) 
    AND 
    (c0_.firstname LIKE ? 
    OR c0_.lastname LIKE ? 
    OR c0_.email LIKE ? 
    OR c0_.company LIKE ? 
    OR c1_.street_address1 LIKE ? 
    OR c1_.street_address2 LIKE ? 
    OR c1_.city LIKE ? 
    OR c1_.state = ? 
    OR c1_.zipcode = ? 
    OR c2_.phone LIKE ? 
) 

Мой конструктор запросов выглядит следующим образом:

public function search($keywords = null, $lead=0){ 
    if ($keywords === null) return $this->findAllOrderedByName($lead); 

    $qb = $this->createQueryBuilder ('c') 
     ->addSelect('a') 
     ->addSelect('p') 
     ->leftJoin('c.addresses', 'a') 
     ->leftJoin('c.phones', 'p'); 
    $qb->where('c.isLead = :lead'); 

    $qb->andWhere('c.firstname like :firstname'); 
    $qb->orWhere('c.lastname like :lastname'); 
    $qb->orWhere('c.email like :email'); 
    $qb->orWhere('c.company like :company'); 

    $qb->orWhere('a.streetAddress1 like :streetAddress1'); 
    $qb->orWhere('a.streetAddress2 like :streetAddress2'); 
    $qb->orWhere('a.city like :city'); 
    $qb->orWhere('a.state = :state'); 
    $qb->orWhere('a.zipcode = :zipcode'); 
    $qb->orWhere('p.phone like :phone'); 

    $qb->setParameter('lead', $lead); 
    $qb->setParameter('firstname', '%' . $keywords . '%'); 
    $qb->setParameter('lastname', '%' . $keywords . '%'); 
    $qb->setParameter('email', '%' . $keywords . '%'); 
    $qb->setParameter('company', '%' . $keywords . '%'); 
    $qb->setParameter('streetAddress1', '%' . $keywords . '%'); 
    $qb->setParameter('streetAddress2', '%' . $keywords . '%'); 
    $qb->setParameter('city', '%' . $keywords . '%'); 
    $qb->setParameter('state', $keywords); 
    $qb->setParameter('zipcode', $keywords); 
    $qb->setParameter('phone', '%' . $keywords . '%'); 
    $qb->orderBy('c.lastname', 'ASC'); 
    return $qb; 
} 

Способ, которым я в настоящее время создаю свой запрос, возвращает результаты, даже если ключевые слова поиска не соответствуют никаким записям из-за соединений, я не знаю, как я могу изменить запрос b uilder метод, любые идеи?

ответ

0

Вы можете написать его как

$qb->andWhere('(c.firstname like :firstname 
       OR c.lastname like :lastname 
       OR c.email like :email 
       OR c.company like :company 
       OR a.streetAddress1 like :streetAddress1 
       OR a.streetAddress2 like :streetAddress2 
       OR a.city like :city 
       OR a.state = :state 
       OR a.zipcode = :zipcode 
       OR p.phone like :phone)'); 
+0

Это сработало для меня. Спасибо – MikeGA

0

Вы пытались использовать addAnd(<condition>) вместо andWhere()?

+0

Это не работает для меня ... 'addAnd 'Это неизвестный метод, я использую доктрину 2.2. – MikeGA

0

Я думаю, вы могли бы использовать в orX, а затем записать его в виде ..

public function search($keywords = null, $lead=0){ 
    if ($keywords === null) return $this->findAllOrderedByName($lead); 

    $qb = $this->createQueryBuilder ('c') 
     ->addSelect('a') 
     ->addSelect('p') 
     ->leftJoin('c.addresses', 'a') 
     ->leftJoin('c.phones', 'p'); 

    $qb->where(
     $qb->expr()->eq('c.isLead', ':lead') 
    )->andWhere(
     $qb->expr() 
      ->orX($qb->expr()->like('c.firstname', ':keywords')) 
      ->add($qb->expr()->like('c.lastname', ':keywords')) 
      ->add($qb->expr()->like('c.email', ':keywords')) 
      ->add($qb->expr()->like('c.company', ':keywords')) 

      ->add($qb->expr()->like('a.streetAddress1', ':keywords')) 
      ->add($qb->expr()->like('a.streetAddress2', ':keywords')) 
      ->add($qb->expr()->like('a.city', ':keywords')) 
      ->add($qb->expr()->eq('a.state', ':keywords')) 
      ->add($qb->expr()->eq('a.zipcode', ':keywords')) 

      ->add($qb->expr()->like('p.phone', 'keywords')) 
    ); 

    $qb->setParameter('lead', $lead); 
    $qb->setParameter('keywords', '%' . $keywords . '%'); 

    $qb->orderBy('c.lastname', 'ASC'); 

    return $qb; 
} 
+0

Этот способ тоже работал для меня. – MikeGA