Katarzyna Kajzar

Katarzyna Kajzar PHP developer

Temat: Zapytanie w Doctrine

Witam!

Mam pytanie, może banalne, ale zajęło mi już trochę czasu dochodzenie jak zrobić, żeby działało, a ono nic!

Czy mógłby ktoś z Was powiedzieć mi jak napisać w doctrine zapytanie, które w MySQL wygląda następująco:


SELECT *
FROM article AS a
INNER JOIN section_article AS sa ON a.id_article = sa.article_id
AND sa.section_id =8
ORDER BY a.`priority` ASC


Mam relacje wiele-do-wielu pomiędzy Section i Article. Bez problemu pobieram sobie sekcję, którą potrzebuję i mam w niej artykuły, ale potrzebuję, żeby były one ustawione ważnością artykułów. Może da się jakoś zmienić to zapytanie:

$this->section = Doctrine_Core::getTable('Section')->find($this->id_section);


żeby było prościej.

Z góry dziękuję za pomoc :)
Katarzyna Kajzar

Katarzyna Kajzar PHP developer

Temat: Zapytanie w Doctrine

Rozwiązanie, jakby kiedyś komuś miało się przydać, wygląda tak:

$this->q = Doctrine_Query::create()
->select('a.content, a.id_article, a.priority')
->from('Article a')
->innerJoin('a.SectionArticle sa')
->where('sa.section_id = ?', $this->id_section)
->orderBy('a.priority ASC')
->limit(1)
->execute()
->toArray();


Pozdrawiam.

konto usunięte

Temat: Zapytanie w Doctrine

Katarzyna Idczak:
Rozwiązanie, jakby kiedyś komuś miało się przydać, wygląda tak:

$this->q = Doctrine_Query::create()
->select('a.content, a.id_article, a.priority')
->from('Article a')
->innerJoin('a.SectionArticle sa')
->where('sa.section_id = ?', $this->id_section)
->orderBy('a.priority ASC')
->limit(1)
->execute()
->toArray();


Pozdrawiam.

Nie polecam takiego rozwiązania, ponieważ domyślnie działa to tak, execute powoduje, że wszystkie dane zostaną pobrane jako obiekty, oraz zostanie zwrócona kolekcja Doctrine_Collection ze zagregowanymi obiektami - jest to rozwiązanie bardzo czasochłonne. Jeśli chcesz odnosić się bezpośrednio w notacji tablicowej (wydajne rozwiązanie), polecam poniższy kod:


$this->q = Doctrine_Query::create()
->select('a.content, a.id_article, a.priority')
->from('Article a')
->innerJoin('a.SectionArticle sa')
->where('sa.section_id = ?', $this->id_section)
->orderBy('a.priority ASC')
->limit(1)
->execute(array(), Doctrine::HYDRATE_ARRAY); // albo Doctrine::HYDRATE_NONE - szybsze


W ten sposób nie jest tworzona kolekcja obiektów tylko tablica asocjacyjna, sprawdź czas działania, gwarantuje, że będzie kilkanaście razy szybszy.
Katarzyna Kajzar

Katarzyna Kajzar PHP developer

Temat: Zapytanie w Doctrine

Dzięki, tak poprawiłam :)
Jakub Zalas

Jakub Zalas Software Engineer,
Symfony Core
Contributor

Temat: Zapytanie w Doctrine

Łukasz Adamczewski:

Nie polecam takiego rozwiązania, ponieważ domyślnie działa to tak, execute powoduje, że wszystkie dane zostaną pobrane jako obiekty, oraz zostanie zwrócona kolekcja Doctrine_Collection ze zagregowanymi obiektami - jest to rozwiązanie bardzo czasochłonne. Jeśli chcesz odnosić się bezpośrednio w notacji tablicowej (wydajne rozwiązanie), polecam poniższy kod:


$this->q = Doctrine_Query::create()
->select('a.content, a.id_article, a.priority')
->from('Article a')
->innerJoin('a.SectionArticle sa')
->where('sa.section_id = ?', $this->id_section)
->orderBy('a.priority ASC')
->limit(1)
->execute(array(), Doctrine::HYDRATE_ARRAY); // albo Doctrine::HYDRATE_NONE - szybsze


W ten sposób nie jest tworzona kolekcja obiektów tylko tablica asocjacyjna, sprawdź czas działania, gwarantuje, że będzie kilkanaście razy szybszy.

Robiłeś testy? Ostatnio, kiedy to sprawdzałem Doctrine oszczędzał tylko nieco pamięci. Nadal "budował" te tablice i nie było to najwydajnieszjsze. Najszybciej jest z HYDRATE_SCALAR (ale nie za wygodnie).

Oczywiście, nie zawsze potrzebujemy, żeby było "najszybciej". Czasem wygoda jest ważniejsza niż wydajność.

konto usunięte

Temat: Zapytanie w Doctrine

Jakub Zalas:
Łukasz Adamczewski:

Nie polecam takiego rozwiązania, ponieważ domyślnie działa to tak, execute powoduje, że wszystkie dane zostaną pobrane jako obiekty, oraz zostanie zwrócona kolekcja Doctrine_Collection ze zagregowanymi obiektami - jest to rozwiązanie bardzo czasochłonne. Jeśli chcesz odnosić się bezpośrednio w notacji tablicowej (wydajne rozwiązanie), polecam poniższy kod:


$this->q = Doctrine_Query::create()
->select('a.content, a.id_article, a.priority')
->from('Article a')
->innerJoin('a.SectionArticle sa')
->where('sa.section_id = ?', $this->id_section)
->orderBy('a.priority ASC')
->limit(1)
->execute(array(), Doctrine::HYDRATE_ARRAY); // albo Doctrine::HYDRATE_NONE - szybsze


W ten sposób nie jest tworzona kolekcja obiektów tylko tablica asocjacyjna, sprawdź czas działania, gwarantuje, że będzie kilkanaście razy szybszy.

Robiłeś testy? Ostatnio, kiedy to sprawdzałem Doctrine oszczędzał tylko nieco pamięci. Nadal "budował" te tablice i nie było to najwydajnieszjsze. Najszybciej jest z HYDRATE_SCALAR (ale nie za wygodnie).

Oczywiście, nie zawsze potrzebujemy, żeby było "najszybciej". Czasem wygoda jest ważniejsza niż wydajność.


Testów nie robiłem, ale powołuje się na

http://www.doctrine-project.org/documentation/manual/1...

gdzie piszą coś w stylu
There are two important differences between HYDRATE_ARRAY and HYDRATE_NONE
which you should consider before choosing which to use. HYDRATE_NONE is the fastest but the result is an array with numeric keys and so results would be > referenced as $result[0][0] instead of $result[0]['my_field'] with
HYDRATE_ARRAY. Best practice would to use HYDRATE_NONE when retrieving large record sets or when doing many similar queries. Otherwise, HYDRATE_ARRAY is more comfortable and should be preferred.

Ale oczywiście dla wyników countów i zwracania wartości pojedynczych kolumn HYDRATE_SCALAR jest najszybszeŁukasz Adamczewski edytował(a) ten post dnia 02.05.11 o godzinie 23:31
Jakub Zalas

Jakub Zalas Software Engineer,
Symfony Core
Contributor

Temat: Zapytanie w Doctrine

Łukasz Adamczewski:

Testów nie robiłem, ale powołuje się na

http://www.doctrine-project.org/documentation/manual/1...

gdzie piszą coś w stylu
There are two important differences between HYDRATE_ARRAY and HYDRATE_NONE
which you should consider before choosing which to use. HYDRATE_NONE is the fastest but the result is an array with numeric keys and so results would be > referenced as $result[0][0] instead of $result[0]['my_field'] with
HYDRATE_ARRAY. Best practice would to use HYDRATE_NONE when retrieving large record sets or when doing many similar queries. Otherwise, HYDRATE_ARRAY is more comfortable and should be preferred.

Nie kwestionuję tego, że HYDRATE_NONE jest szybsze niż HYDRATE_ARRAY. Dyskutowałbym nad tym, że HYDRATE_ARRAY jest dużo szybsze od budowania obiektów.

IMHO jest to istotne tylko w krytycznych punktach naszych aplikacji.

konto usunięte

Temat: Zapytanie w Doctrine

Nie kwestionuję tego, że HYDRATE_NONE jest szybsze niż HYDRATE_ARRAY. Dyskutowałbym nad tym, że HYDRATE_ARRAY jest dużo szybsze od budowania obiektów.

IMHO jest to istotne tylko w krytycznych punktach naszych aplikacji.

Masz absolutną rację, z kolei ja mówiłem to w kontekście zupełnie innego problemu bo


$this->q = Doctrine_Query::create()
->select('a.content, a.id_article, a.priority')
->from('Article a')
->innerJoin('a.SectionArticle sa')
->where('sa.section_id = ?', $this->id_section)
->orderBy('a.priority ASC')
->limit(1)
->execute()
->toArray();


w zapytaniu które przedstawiła koleżanka są po sobie execute a potem toArray() czyli najpierw budowana jest kolekcja obiektów Doctrine_Collection a potem tablica asocjacyjne i głownie na tym polegała moja uwaga, a kwestie różnic widać przy fetchach rzędu tysiąc i więcej.

Pozdrawiam

Ps. niedawno utworzyłem konto na symfonyexperts i widzę, że ładnie tam kasujesz :P



Wyślij zaproszenie do