【问题标题】:Laravel Eloquent self relation query to return nested JSONLaravel Eloquent 自关系查询返回嵌套 JSON
【发布时间】:2019-02-26 04:53:47
【问题描述】:

我有一个具有一对一自我关系的表来表示层次结构。下面是表格的示意图和一些示例数据:

这是关系的位置模型代码:

class Location extends Model
{
    public function location()
    {
        return $this->hasOne('App\Location');
    }
}

我想查询 Locations 表并发送 JSON 响应,如下例所示,但我不确定如何处理查询:

{
    "id": 1,
    "name": "Country",
    "location_id": null
    "location": {
        "id": 2,
        "name": "State",
        "location_id": 1
        "location": {
            "id": 3,
            "name": "City",
            "location_id": 2
        }
    }
}

【问题讨论】:

  • 这不应该是一对多的关系吗?一个国家可以有很多城市,但一个城市只能在一个国家。查询的方法取决于您真正想要如何播放它,如果您可能有数百万条记录,您是否要加载所有记录并全部显示?也许您只想显示这么多级别,或者只是直系子级?有很多不同的方法可以做到这一点,所以答案真的取决于你想要什么。
  • 预期深度是多少? 2、4、10、20 级?
  • @Jonathon 这只是一个例子我确信我的项目只需要一个线性层次结构
  • @Kyslik 深度将是动态的,可以嵌套任意数量的位置
  • 你愿意使用 PostgresSQL 吗?我怀疑(谁知道)你可以在 Eloquent 本身中做到这一点,你可以试试en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL 整张桌子会有多少个位置? 1k,100k? 1米?您可以抓取所有位置并在 PHP 中完成。

标签: json laravel api eloquent


【解决方案1】:

要始终急切地加载位置关系而不担心深度,您可以将 $with 属性添加到您的位置模型中:

protected $with = ['location'];

现在,当您返回一个位置时,它将加载所有嵌套的子位置:

return App\Location::find(1);

如果它是从控制器方法返回的,Laravel 也会处理将它作为 JSON 返回。

正如 Kyslik 所指出的,这提出了一个潜在的 N+1 问题,在决定在生产中使用这样的解决方案时,应考虑潜在的深度以及查询大小和环境的其余部分,例如地点,这可能不是问题,非常值得简单

【讨论】:

  • 是的,但这是 n+1 的问题。正如 OP 所建议的那样,它可以是数百个嵌套位置,在这种情况下,最好加载所有内容并在纯 PHP 中完成。
  • 这可行,但如果我需要关闭 with 怎么办?
  • op 能否确认它可能有数百层深?我认为 op 只是不想给出具体数字,但我想如果它真的被用于位置,这仍然是一个可行的选择。
  • @mattQuest 我想我会限制用户只有几个(7、8)个子位置,这应该足以满足他们的目的,所以性能不会成为问题,谢谢跨度>
  • 如果您需要 Laravel 中的高性能分层数据,请查看 github.com/lazychaser/laravel-nestedset
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 2020-03-19
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多