我正在尝试从数据库中导出大量记录,但我需要关系数据才能正确构建导出。理想情况下,我能够使用cursor()
来获取延迟集合,但这不会加载关系。我无法在循环中加载关系,因为这将创建 N+1 查询,并且这可能是数十万个额外查询,这是不可接受的。
这是“有效”的(但内存不足):
Record::with('projects')->get()->map(function ($record) {
dd($record); // Shows the `projects` relationship
});
Run Code Online (Sandbox Code Playgroud)
但是当我使用cursor()
...
Record::with('projects')->cursor()->map(function ($record) {
dd($record); // Does NOT show the `projects` relationship
});
Run Code Online (Sandbox Code Playgroud)
有没有办法获得包含记录关系的惰性集合?我查看了文档,并不清楚。其他建议是使用chunk()
,不幸的是在这种情况下不可能。
编辑:我不应该说块是不可能的,但这是一个非常昂贵的重写。目前,数据的结构具有很大的可变性。因此,为了构建用于导出的 CSV,我需要(例如)文件的标头。目前,我通过循环遍历所有记录(字段存储在 JSONB 字段中)并根据这些记录中存在的字段构建一个数组来获取该标头。
我还根据这些标头对数据进行标准化。因此,如果一条记录具有“address-1”字段,但另一条记录没有该字段,则没有该字段的记录会在相应列中显示空白值。否则,将行插入 CSV 时,它不会考虑标题。
目前,这些操作会获取整个数据集,并使用 LazyCollection 来映射标头并规范化记录,然后将其一次一个地输入到 CSV 中。如果我也可以获取 LazyCollection 中的关系而不必重写工作流程,那就太理想了。