Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
chcę napisać system komentarzy z odpowiedziami, lecz problem mam z efektywnym (nie zajeżdżającym bazę) pobraniem rekordów wraz z zagłębieniem.. Przyjrzałem się platformie Wordpress.. w strukturze bazy widzę że nie jest to oparte na drzewkach (nie mam tam _left i _right) jest tylko comment_parent_ID - czyli ID rodzica.. zauważyłem też że ten CMS tworzy odpowiedzi max do 4 zagłębienia ... na wp widzę do pierwszego..wie ktoś jak pobrać rekordy od razu w odpowiedniej kolejności oraz zagłębieniem??
Krzysztof
N.
Project Manager.
Aplikacje www. PHP,
Symfony, Zend.
Temat: Pobranie komentarzy z odpowiedziami
Michał Sosnowski:Pierwsza myśl jaka się nasuwa to właśnie drzewo left-right.
wie ktoś jak pobrać rekordy od razu w odpowiedniej kolejności oraz zagłębieniem??
Michał
Wachowski
Freelancer na
zakręcie i
bazodanowiec z
bożej łaski
Temat: Pobranie komentarzy z odpowiedziami
Jeżeli ograniczy się do 1-2 poziomów (0 to standardowe komentarze), to parent_id w zupełności wystarczy.Odczytujesz jak leci i albo po odczycie, albo w trakcie układasz w wielowymiarową tablicę.
Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
W szumie 1-2 poziomy mi wystarczą.. WP.pl ma do 1 poziomu.. Wordpress do czwartego.. W sumie jak będę odczytywał jak leci - to nie mam pomysłu jak obliczać zagłębienie
Michał
Wachowski
Freelancer na
zakręcie i
bazodanowiec z
bożej łaski
Temat: Pobranie komentarzy z odpowiedziami
Jeżeli odczytujesz jak leci to:- zapisujesz elementy w tablicy z id jako kluczami,
- podczas odczytywania ustawiasz zagłębienie na 0, każdemu elementowi,
- po odczycie sortujesz wszystko od najgłębszego do najpłytszego.
- potem tylko odpalasz pętlę, gdzie przypisujesz elementy do rodziców, po przypisaniu usuwasz je z tablicy.
W efekcie otrzymasz tablicę wielowymiarową, gdzie na pierwszym poziomie masz tylko elementy z głębokością 0 (czy tam 1, zależy od czego zaczniesz liczyć).
Jako że odczyt jest częstszy niż zapis, lepiej będzie jeśli głębokość będziesz trzymał w danym komentarzu i odczytywał już od najgłębszego do najpłytszego.
Ważnym jest też, by osobno oznaczać wątek, którego się tyczy i osobno rodzica - komentarz nadrzędny.
Dariusz Półtorak Programista PHP
Temat: Pobranie komentarzy z odpowiedziami
Sortować nie trzeba. Każdy kolejny wpis jest nowszy od poprzedniego więc ułożą się w naturalnym porządku. Ja sobie zrobiłem to na rekurencji (przez co nie mam ograniczenia do zagłębień) a całość nie jest specjalnie ciężka jeżeli nie planujesz tam mieć tysięcy zagnieżdżonych wpisów.Akurat drzewko mam na smarty a że jest bardzo prościutkie i modyfikowane dość często więc nested set model mi nie pasował.
1. A sprawa jest prosta. Pobierasz posortowane wg id rekordy.
2. Przepisujesz tablicę tak by jej kluczem był parentId
3. Kierujesz taką tablicę do smarty lub innego systemu szablonów ze zmienną która mówi by iterować tylko te pod kluczem 0 (czyli pień)
W tym momencie masz to co najważniejsze czyli wypisany główny pień bez dzieci. Teraz wystarczy zrobić prostą sztuczkę. Albo wewnątrz szablonu albo w php.
4. Kiedy dochodzimy do wypisywania <li> tytul {KOLEJNA LISTA} to w {KOLEJNA LISTA} powinniśmy wsadzić kod który ponownie doda szablon i przypisze mu zmienną mówiącą by iterować z klucza parentId == id elementu który akurat wypisujemy.
I tak ile mamy zagnieżdżeń tyle razy się doda plik szablonu a przestawiona zmienna zapewni wypisanie dokładnie tego co potrzebujemy. Nested Set Model do komentarzy tam gdzie będą one dodawane często nigdy nie polecam z uwagi na to że trzeba 3 zapytania na każdą modyfikację gdzie tutaj wystarczy jedno. Chyba że zrobimy to co dodałem w jednym serwisie gdzie musieliśmy mieć Nested Set Model z uwagi na to że trzeba było dużo rzeczy robić na wpisach. Dodaliśmy treeId i tak tabela składała się z setek "pod drzewek" przez co modyfikowaliśmy rekordy tylko z aktualnego wpisu.
Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
Owszem każdy komentarz jest nowszy, ale jak ktoś odpowie na pierwszy komentarz to nie może być to sortowane po ID lub dacie dodania.. spróbuję coś pokombinować..
Łukasz K. Programista PHP
Temat: Pobranie komentarzy z odpowiedziami
Michał Sosnowski:True, zwłaszcza, że często pobiera się dane limitowane ( stronicowanie ).
Owszem każdy komentarz jest nowszy, ale jak ktoś odpowie na pierwszy komentarz to nie może być to sortowane po ID lub dacie dodania.. spróbuję coś pokombinować..
Dawid
Pakuła
właściciel,
w3des.net
Temat: Pobranie komentarzy z odpowiedziami
Spróbuj trzymać parent_id (dla relacji np) + path wtedy niema problemu z pobieraniem z zagłębieniem ;) Wystarczy order by path asc, created_at desc tak na przykład i szybkie budowanie drzewka przy czytaniu wynikuBranie kolejności prosto z bazy (bez order by) to kiepski pomysł. Taki postgreSQL np różnie reaguje.
Karol Tarasiuk Web Developer
Temat: Pobranie komentarzy z odpowiedziami
Myślę, że samo pobranie struktury może być zrobione tak jak już koledzy wspomnieli.Pamiętaj tylko, że taka wielowymiarowa struktura danych musi być przygotowana pod kątem stronicowania, wybierania pojedynczych komentarzy i dowolnego podzbioru komentarzy.
I co najważniejsze powinien być tam jakiś cache, aby całość nie była wykonywana przy każdym rozkazie, a raczej cyklicznie co jakiś czas.
Dariusz Półtorak Programista PHP
Temat: Pobranie komentarzy z odpowiedziami
Michał Sosnowski:
Owszem każdy komentarz jest nowszy, ale jak ktoś odpowie na pierwszy komentarz to nie może być to sortowane po ID lub dacie dodania.. spróbuję coś pokombinować..
To nie problem. Wypisywanie wygląda mniej i więcej tak
ID / PARENT
1 / 0
2 / 0
3 / 0
4 / 2
5 / 2
6 / 4
7 / 6
8 / 6
9 / 0
Przepisujemy tak by klucz był 0 i wypisujemy najpierw te z 0 jako parentId więc dostaniemy na poziomie 1:
1
2
3
9
Przy każdej iteracji działa rekurencja dla kolejny parentId == id więc dostaniesz dokładnie taką strukturę
- 1
- 2
-- 4
--- 6
---- 7
---- 8
-- 5
- 3
- 9
Z uwagi na to że przy elemencie 2 zostanie zaincludowany szablon który wypisze te elementy które mają parent 2. Później te z parent 4 i 6.
Fakt że będzie problem ze stronnicowaniem mały. Jeżeli Ci na nim bardzo zależy to chyba nested set model będzie lepszy.Dariusz Półtorak edytował(a) ten post dnia 01.02.12 o godzinie 09:21
Michał
Wachowski
Freelancer na
zakręcie i
bazodanowiec z
bożej łaski
Temat: Pobranie komentarzy z odpowiedziami
Jeżeli potrzebne jest stronicowanie, to lepszym rozwiązaniem będzie wersja podobna do onet'owej - gdzie komentarze traktuje się jako "wątki" z możliwością wejścia.Rozwiązań jest wiele - swojego czasu widziałem, że ktoś prezentował komentarze z dowolną ilością zagłębień w postaci drzewka z rozwijanymi ajax'owo gałęziami.
Wojciech
K.
realizator
pomysłów własnych
Temat: Pobranie komentarzy z odpowiedziami
Michał Sosnowski:
wie ktoś jak pobrać rekordy od razu w odpowiedniej kolejności oraz zagłębieniem??
jeśli z góry zakładasz ograniczenie zagłębienia do np. 4,
to możesz stworzyć (indeksowane) pola: grandgrandparent,grandparent
wypełniasz je stosownymi danymi - robiąc jednorazowe rekurencyjne sprawdzenie parent_id TYLKO PRZY DODANIU komentarza....
przy odczytywaniu nie musisz wtedy stosować rekurencji - tylko ściągasz tablicę JEDNYM ZAPYTANIEM posortowaną po polach grandgrandparent,grandparent,parent_id,id
co więcej - możesz wtedy dowolnie stronicować - lista może być ucięta w połowie zagnieżdżenia i dalej zaczynać się w tym samym miejscu....
Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
funkcję rekurencyjną mam napisaną (sprawdzenie czy dane ID ma w bazie odpowiedzi - jeśli ma to znów jest wywoływana).. Problem leży w czym innym.. chce się trzymać modelu MVC i dlatego w modelu chce najpierw przygotować tablicę do wyświetlenia.. więc w funkcji po prostu (na razie) zrzucam ID do tablicy :$comments[] = $r['comment_ID'];
to rozwiązanie zwraca mi kilka tablic zamiast jednej ;/ jak zrobić żeby funkcja rekurencyjna zwróciła jedną tablicę według oczekiwanego porządku ??
Michał
Wachowski
Freelancer na
zakręcie i
bazodanowiec z
bożej łaski
Temat: Pobranie komentarzy z odpowiedziami
Operuj wciąż na tej samej tablicy - przekazuj ją jako parametr do funkcji przez referencje.Albo wynik funkcji, przypisuj do istniejącej tablicy.Michał Wachowski edytował(a) ten post dnia 02.02.12 o godzinie 14:50
Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
niestety nie wychodzi mi (choć pewnie po prostu źle to robię) dla ułatwienia podam tą funkcję :function get_comments($post, $ID) {
global $PF;
$result = $PF -> query("SELECT * FROM ".$PF -> prefix."comments WHERE comment_news_ID = ".$post." AND comment_parent_ID = ".$ID." ORDER BY comment_create ASC");
while ($r = mysql_fetch_assoc($result)) {
$comments[] = $r['comment_ID'];
if(has_replies($r['comment_ID'])) get_comments ($post, $r['comment_ID']);
}
return $comments;
}Michał Sosnowski edytował(a) ten post dnia 02.02.12 o godzinie 15:08
Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
podana powyżej funkcja tworzy mi np.: Array([0] => 28) Array([0] => 26 [1] => 27)cokolwiek chciałbym żeby to było jedna tablica: Array([0] => 26 [1] => 28 [2] => 27)
Ma ktoś pomysł?
Michał Sosnowski grafik/webmaster
Temat: Pobranie komentarzy z odpowiedziami
Oka już poradziłem sobie.. użyłem funkcji array_merge() :function get_comments($post, $ID) {
global $PF;
$result = $PF -> query("SELECT * FROM ".$PF -> prefix."comments WHERE comment_news_ID = ".$post." AND comment_parent_ID = ".$ID." ORDER BY comment_create ASC");
while ($r = mysql_fetch_assoc($result)) {
$comments[] = $r['comment_ID'];
if(has_replies($r['comment_ID'])) $comments = array_merge($comments, get_comments ($post, $r['comment_ID']));
}
return $comments;
}
