我有一个论坛系统与许多类别,其中有许多线程,其中有许多帖子。
因此,对于给定的论坛,我应该能够计算出特定论坛的最后一篇帖子。一个论坛可以有许多子论坛(也就是子论坛)。我只能做到其中的一部分。
表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 |下面是我的代码:
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;
}正如您所看到的,lastPost()被调用,直到论坛不再有子论坛为止。我正在从一个子论坛的最新帖子中获得最后一篇帖子。到目前一切尚好。然而,最后的帖子将是子论坛的顺序。因此,如果最后一个帖子在倒数第二个子论坛中,它会返回最后一个子论坛的最后一个帖子,因为最后一个论坛是在递归中最后返回的。
我该如何解决这个问题呢?
谢谢!
发布于 2016-05-11 04:24:47
我认为你应该用不同的方法来解决这个问题。当您有相当多的用户时,您尝试这样做的方式会使数据库崩溃。如果你知道这棵树有多深,最好像这样做大量的“左连接”:
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;在本例中,您将只执行一次查询,在本例中,您将执行n+1查询,如果使用延迟加载,则会执行更多查询。
另一种方法是创建一个"path“列,比如'1/5/19/27/34',它将指示所有的父ids。
您还可以创建一个"last_post“表,它将显示每个类别的最后一篇文章。这也会提高你的表现。
这篇文章有很多信息:How to create a MySQL hierarchical recursive query
发布于 2016-05-11 05:26:06
Alter recursive function接受post参数并比较日期。
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;
}然而,正如Felippe Duarte所说,递归查询数据库是一件坏事,所以如果你打算在生产中使用论坛,请寻找替代方案。
https://stackoverflow.com/questions/37146943
复制相似问题