2016-05-10 26 views
0

Ich habe ein Forum-System mit vielen Kategorien, die viele Threads hat, die viele Beiträge hat.Laravel Rekursion - Suche nach dem "letzten Beitrag"

Also mit gegebenen Forum sollte ich in der Lage sein, herauszufinden, der letzte Beitrag, dass bestimmte Forum hat. Ein Forum kann viele Unterforen (alias Kinder) haben. Ich konnte nur einen Teil davon machen.

Tabelle Demo:

| id | parent_id | name    | is_category | 
|----|-----------|-------------------|-------------| 
| 1 | 0   | Suggestions  | 1   | 
| 2 | 1   | site suggestions | 0   | 
| 3 | 1   | forum suggestions | 0   | 
| 4 | 2   | bugs    | 0   | 

Hier ist mein Code:

public function lastPost() 
{ 
    foreach ($this->threads()->orderBy('updated_at')->get() as $thread) { 
     $post = $thread->lastPost(); 
    } 
    if ($this->hasSubforum()) { 
     foreach ($this->subforums as $subforum) { 
      $post = $subforum->lastPost(); 
     } 
    } 
    return $post; 
} 

Wie Sie sehen können, lastPost() genannt wird, bis das Forum nicht mehr Subforen hat. Ich bekomme den letzten Beitrag vom letzten Thread in einem Unterforum. So weit, ist es gut. Der letzte Post wäre jedoch die Reihenfolge, in der sich das Unterforum befindet. Wenn also der letzte Post im zweitletzten Unterforum war, gibt er den letzten Post des letzten Unterforums zurück, da das letzte Forum zuletzt in der Rekursion zurückgegeben wurde.

Wie kann ich das beheben?

Danke!

+0

Überprüfen Sie das Datum und stellen Sie nur $ post ein, wenn das Datum jünger ist (oder sogar die id der Post - vorausgesetzt, es gibt eine - vorausgesetzt, es ist seriell)? –

+0

Sie können wahrscheinlich die letzte Methode auf Ihrer $ this-> threads() ... etc Sammlung verwenden, richtig? https://laravel.com/docs/5.1/collections#method-last – ExohJosh

Antwort

1

Ich denke, Sie sollten einen anderen Ansatz für dieses Problem tun. Die Art und Weise, wie Sie versuchen, wird Ihre Datenbank zum Absturz bringen, wenn Sie eine beträchtliche Anzahl von Benutzern haben. Wenn Sie wissen, wie tief würde dieser Baum sein, ist es besser für die Leistung viel zu tun „LEFT JOIN“ wie folgt aus:

select d3.parent_id as parent3_id, 
     d2.parent_id as parent2_id, 
     d1.parent_id as parent_id, 
     d1.id as product_id, 
     d1.name 
from  demo d1 
left join demo d2 on d2.id = d1.parent_id 
left join demo d3 on d3.id = d2.parent_id 
... join as many as you think it will have data ... 
where $this->id in (d1.parent_id, 
       d2.parent_id, 
       d3.parent_id) 
order by 1, 2, 3; 

In diesem Fall werden Sie nur 1 Abfrage tun, in Ihrem Fall werden Sie tun n + 1 Abfragen oder noch mehr, wenn Sie lazy loading verwenden.

Eine andere Möglichkeit besteht darin, eine "Pfad" -Spalte wie "1/5/19/27/34" zu erstellen, die alle übergeordneten IDs angibt.

Sie können auch eine Tabelle "last_post" erstellen, die angibt, was der letzte Post für jede Kategorie war. Es wird auch Ihre Leistung verbessern.

Dieser Beitrag hat eine Menge Informationen: How to create a MySQL hierarchical recursive query

+0

Leider weiß ich nicht, wie tief es sein wird –

0

Alter rekursive Funktion einen Beitrag Parameter und vergleichen Daten zu akzeptieren.

public function lastPost($post = null) 
{ 
    foreach ($this->threads()->orderBy('updated_at')->get() as $thread) { 
     $cur_post = $thread->lastPost(); 
     if ($post === null) { 
      $post = $cur_post; 
     } 
     else { 
      $cur_post_date = new DateTime($cur_post->date_added); // Or whatever you use to get last post date 
      $post_date = new DateTime($post->date_added); 
      if ($cur_post_date > $post_date) { 
       $post = $cur_post; 
      } 
     } 
    } 
    unset($cur_post, $cur_post_date, $post_date); 
    if ($this->hasSubforum()) { 
     foreach ($this->subforums as $subforum) { 
      $post = $subforum->lastPost($post); 
     } 
    } 
    return $post; 
} 

jedoch als Felippe Duarte sagte rekursiv die Datenbank ist eine schlechte Sache, so suchen Sie nach Alternativen abfragt, wenn Sie das Forum in der Produktion verwenden werden.

Verwandte Themen