Laravel eloquent 如何从集合集合中预加载和获取单独数组中的关系
Laravel eloquent how to eager load and get relations in seperate array from collection of collections
我在获取单独数组中的 parent 和 child 记录时遇到问题。
例如,我有 2 个模型:
1) 锦标赛 (parent): 锦标赛有很多项目
public function events(){
return $this->hasMany(Event::class);
}
2) 赛事 (child): 赛事属于锦标赛
public function tournament(){
return $this->belongsTo(Tournament::class);
}
我根据发送到控制器的请求中的参数过滤事件。过滤器是 'away_team'、'home_team'、'tournament_id'。我过滤掉事件,然后尝试加载事件所属的锦标赛。
之后,我尝试获取锦标赛并将它们分别放入数组中。但它抛出内存允许错误。
我知道我可以增加 php.ini 中的内存,但我想以最好的方式参加锦标赛 - 最好是 eloquent 查询 - 并减少内存使用。我已经在活动中有锦标赛,但问题是活动在一个集合中,所以我如何根据请求输入查询设法在单独的集合中同时获得活动和独特的锦标赛。
这是我到目前为止设法完成的代码。我知道它有效,但它会引发错误,因为我有 10,000 条或更多条记录:
public functions filter(Request $request){
$query = App\Model\Event::query();
if ($request->has('away_team')) {
$query = $query->where('away_team.name', 'like', '%' . $request->away_team . '%');
}
if ($request->has('home_team')) {
$query = $query->where('home_team.name', 'like', '%' . $request->home_team . '%');
}
if ($request->has('tournament_id')) {
$query = $query->where('tournament_id', new ObjectID($request->tournament_id));
}
//events collection with tournament
$events = $query->with('tournament')->get();
//here I get Allowed memory error
$tournaments = [];
foreach ($events as $event) {
$tournaments[] = $event->tournament;
}
$tournaments = array_unique($tournaments);
}
那么,根据这些条件将这些模型记录放入单独的集合中的解决方案是什么:
1) 事件必须匹配 $request 过滤器
2) 锦标赛必须是唯一的并且属于数据库事件结果
PS: 我用 PHP-mongo 和 Laravel eloquent for mongo db
PS2: 我知道 mongo 不是关系型的,但你可以像某种方式使用它关系型
如有任何帮助,我们将不胜感激!提前致谢。
您可以将这些请求一分为二,但我不确定这是否会减少对内存的需求。
public functions filter(Request $request)
{
$eventQuery = App\Model\Event::query();
$tournamentQuery = App\Model\Tournament::query();
if ($request->has('away_team')) {
$eventQuery = $eventQuery->where('away_team.name', 'like', '%' . $request->away_team . '%');
}
if ($request->has('home_team')) {
$eventQuery = $eventQuery->where('home_team.name', 'like', '%' . $request->home_team . '%');
}
if ($request->has('tournament_id')) {
$eventQuery = $eventQuery->where('tournament_id', new ObjectID($request->tournament_id));
}
//events collection with tournament
$events = $eventQuery->get();
// Get only tournaments that belongs to selected events.
$tournaments = $tournamentQuery->whereIn('id', $events->pluck('tournament_id')->all())->get()
}
顺便说一句,我认为,如果锦标赛拥有赛事,您应该在 Tournament
class event()
方法和 [=15= 方法中调用 hasMany()
] class反过来
还可以对每个赛事加载的锦标赛数量进行限制。只需像这样更改您的最后一个查询:
public function filter(Request $request)
{
// ... your code
$events = $query->with('tournament', function ($query) {
$query->limit(10);
})->get();
// ... rest of your code
}
我在获取单独数组中的 parent 和 child 记录时遇到问题。 例如,我有 2 个模型:
1) 锦标赛 (parent): 锦标赛有很多项目
public function events(){
return $this->hasMany(Event::class);
}
2) 赛事 (child): 赛事属于锦标赛
public function tournament(){
return $this->belongsTo(Tournament::class);
}
我根据发送到控制器的请求中的参数过滤事件。过滤器是 'away_team'、'home_team'、'tournament_id'。我过滤掉事件,然后尝试加载事件所属的锦标赛。
之后,我尝试获取锦标赛并将它们分别放入数组中。但它抛出内存允许错误。
我知道我可以增加 php.ini 中的内存,但我想以最好的方式参加锦标赛 - 最好是 eloquent 查询 - 并减少内存使用。我已经在活动中有锦标赛,但问题是活动在一个集合中,所以我如何根据请求输入查询设法在单独的集合中同时获得活动和独特的锦标赛。
这是我到目前为止设法完成的代码。我知道它有效,但它会引发错误,因为我有 10,000 条或更多条记录:
public functions filter(Request $request){
$query = App\Model\Event::query();
if ($request->has('away_team')) {
$query = $query->where('away_team.name', 'like', '%' . $request->away_team . '%');
}
if ($request->has('home_team')) {
$query = $query->where('home_team.name', 'like', '%' . $request->home_team . '%');
}
if ($request->has('tournament_id')) {
$query = $query->where('tournament_id', new ObjectID($request->tournament_id));
}
//events collection with tournament
$events = $query->with('tournament')->get();
//here I get Allowed memory error
$tournaments = [];
foreach ($events as $event) {
$tournaments[] = $event->tournament;
}
$tournaments = array_unique($tournaments);
}
那么,根据这些条件将这些模型记录放入单独的集合中的解决方案是什么:
1) 事件必须匹配 $request 过滤器
2) 锦标赛必须是唯一的并且属于数据库事件结果
PS: 我用 PHP-mongo 和 Laravel eloquent for mongo db
PS2: 我知道 mongo 不是关系型的,但你可以像某种方式使用它关系型
如有任何帮助,我们将不胜感激!提前致谢。
您可以将这些请求一分为二,但我不确定这是否会减少对内存的需求。
public functions filter(Request $request)
{
$eventQuery = App\Model\Event::query();
$tournamentQuery = App\Model\Tournament::query();
if ($request->has('away_team')) {
$eventQuery = $eventQuery->where('away_team.name', 'like', '%' . $request->away_team . '%');
}
if ($request->has('home_team')) {
$eventQuery = $eventQuery->where('home_team.name', 'like', '%' . $request->home_team . '%');
}
if ($request->has('tournament_id')) {
$eventQuery = $eventQuery->where('tournament_id', new ObjectID($request->tournament_id));
}
//events collection with tournament
$events = $eventQuery->get();
// Get only tournaments that belongs to selected events.
$tournaments = $tournamentQuery->whereIn('id', $events->pluck('tournament_id')->all())->get()
}
顺便说一句,我认为,如果锦标赛拥有赛事,您应该在 Tournament
class event()
方法和 [=15= 方法中调用 hasMany()
] class反过来
还可以对每个赛事加载的锦标赛数量进行限制。只需像这样更改您的最后一个查询:
public function filter(Request $request)
{
// ... your code
$events = $query->with('tournament', function ($query) {
$query->limit(10);
})->get();
// ... rest of your code
}