Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Frameworki _ [SF2][SF][Doctrine2] Problem z zapytaniem orWhere/andWhere

Napisany przez: swiezak 1.03.2016, 13:38:30

Na poczatek struktura bazy danych:
produkt
id name price ...

products_categories
product_id category_id

categories
id name ...


attributes
id name

attribute_sets
id attribute_id product_id value

categories_attributes
category_id attribute_id

Mam formularz z multiselektami, ktory przekazuje do funkcji z repozytorium parametry, w tym id wartosci cechy produktu.
Probuje przy uzyciu query buildera wykonac zapytanie, ktore by mi zwrocilo pasujace rekordy - liste produktow z wartosciami cech zaznaczonych w formularzu. Jednak mam problem, bo gdy uzyje orWhere panuje istny chaos - zwracane sa niepoprawne wyniki, jesli zas uzyje andWhere pojawiaja sie poprawne wyniki, ale brane sa pod uwage tylko przekazane parametry z ostatniego checkboxa w ostatnim multiselekcie.

Zaznaczam w formularzu przykladowo (cecha | wartosc cechy):
pierwszy multiselect: kolor (pobierane jest id cechy) | bialy (pobierana jest wartosc cechy jako string)
drugi multiselect: typ (pobierane jest id cechy) | prawe (pobierana jest wartosc cechy jako string)

  1. class ProductsRepository extends \Doctrine\ORM\EntityRepository
  2. {
  3. public function search($searchParam) {
  4. http://www.php.net/extract($searchParam);
  5.  
  6. $qb = $this->createQueryBuilder('p')
  7. ->leftJoin('p.brands', 'b')
  8. ->addSelect('b')
  9. ->leftJoin('p.categories', 'c')
  10. ->addSelect('c')
  11. ->leftJoin('p.attributeSets', 't') // wartosci cech produktow
  12. ->addSelect('t');
  13.  
  14. if(!http://www.php.net/empty($brandId))
  15. $qb->andWhere('b.id = :brands')->setParameter('brands', $brandId);
  16. if(!http://www.php.net/empty($catId))
  17. $qb->andWhere('c.id = :categories')->setParameter('categories', $catId);
  18. if(!http://www.php.net/empty($attributeSetsVal)){
  19. http://www.php.net/print_r($attributeSetsVal); // zwracane jest: Array ( [6] => Array ( [0] => bialy ) [7] => Array ( [0] => prawe ) ) 6 i 7 to id cechy produktu
  20.  
  21. foreach($attributeSetsVal as $attribute){
  22. $qb->andWhere('t.value = :attributeSets')->setParameter('attributeSets', $attribute); // problem jest z tym fragmentem, zwracane sa poprawne wyniki, ale tylko dla zaznaczonego ostatniego checkboxa z multiselekta
  23. }
  24. }
  25. }


Czy ktos z Was ma jakis pomysl w jaki sposob poprawic zapytanie?

Napisany przez: Riggs 2.03.2016, 07:27:43

Przecież ten zapis w pętli nadpisze ci bindowaną wartość parametru na ostatni element tablicy... Musiałbyś mieć unikalne nazwy parametrów. Z resztą zrzuć sobie zapytanie poprzez $qb->getQuery()->getSQL() i zobaczysz, że będziesz miał kilka takich samych where.

Napisany przez: Crozin 2.03.2016, 08:02:53

Odstawiając temat Doctrine'a na chwilę, rozwiązanie samo w sobie: http://stackoverflow.com/questions/927724/what-is-a-sql-statement-to-select-an-item-that-has-several-attributes-in-an-item - przeniesienie tego do ORM-a nie będzie wielce skomplikowane.

PS. Zastanów się od razu czy nie skorzystać z narzędzi typu Apache SOLR, które zdecydowanie lepiej radzą sobie z wyszukiwaniem.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)