【发布时间】:2020-11-25 08:32:01
【问题描述】:
我有下表:
| node_id | node_name | parent_id |
| 1 | Node 1 | |
| 2 | Node 2 | 1 |
| 3 | Node 3 | 1 |
| 4 | Node 4 | 2 |
我想递归检索特定节点下的所有节点。
我的模型如下所示:
class Tree extends Model
{
public function parent()
{
return $this->belongsTo(self::class, 'node_id');
}
public function children()
{
return $this->hasMany(self::class, 'parent_id', 'node_id');
}
public function allchildren()
{
return $this->hasMany(self::class, 'parent_id', 'node_id')->with('allchildren');;
}
}
现在,如果我想检索一个节点的所有后代,我执行以下操作:
$node = Tree::where('node_id', 1)->first();
$nodes = $node->allchildren;
然而,上面的代码只返回第一级而忽略了更深层次的子级。
我在这里做错了什么?
编辑
事实上,我现在明白我实际上是在正确检索所有数据,只是我看到了输出数组的顶层。
问题是如何展平输出以显示单个数组中的数据?
编辑 2
所以我设法创建了一个函数,使用以下代码(例如在控制器中)将输出平面化为一级数组:
public function flattenTree($array)
{
$result = [];
foreach ($array as $item) {
$result[] = ['node_id'=>$item['node_id'], 'node_name'=>$item['node_name']];
$result = array_merge($result, $this->flattenTree($item['allchildren']));
}
return array_filter($result);
}
然后这样称呼它:
$flatTree = $this->flattenTree($nodes);
【问题讨论】:
-
with将执行一次select if exists。它不是递归操作。您可以查看对子集合执行一些逻辑以获取所有节点。
标签: laravel eloquent self-join