基于第一个查询的预加载
Eager-Loading based on the first query
Query where the problem lies
\DB::enableQueryLog();
$place = Place::near($user)->with(['services','services.registrable' => function (MorphTo $query) {
$query->where('distance_of_visibility', '<', \DB::raw('places.distance'));
}])->find(22);
\DB::disableQueryLog();
dd(\DB::getQueryLog());
Generated queries
首先:查询将计算给定半径内的所有地点,并将计算的字段 distance 添加到 select
select *, st_distance_sphere(`location`, ST_GeomFromText(0.000000 00.000000)) as distance from `places` where st_distance_sphere(`location`, ST_GeomFromText(0.000000 00.000000)) <= 5000 and `places`.`id` = 22 limit 1
第二:with
将预加载 services
select * from `services` where `services`.`place_id` in (22)
最后:with
将尝试加载 registrable
但急切加载给出了 一个明显的错误,因为 places.distance 在此范围内不存在
select * from information where distance_of_visibility < places.distance and information.id in (5)
哪个抛出
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'places.distance' in 'where clause'
What am I trying to do
假设地点的计算字段距离 returns值55米
我只想在 distance_of_visibility 低于 55 米时(通过服务)加载信息.
所以我的问题是:我怎样才能让它以最有效的方式工作。计算距离需要一些查询时间。我会尽量避免加入 table + 重新计算。我想有一种方法可以访问 $query
之前的查询结果,但我不知道如何访问。
Context in case you need more information
放置模型
1.它使用https://github.com/grimzy/laravel-mysql-spatial
2.是hasMany
服务
3. 它包含一个将计算字段 distance 添加到 select:
的范围
/**
* Get the places near the user in a certain radius
* It also add the distance in the select statement
*
* @param SpatialBuilder $query
* @param Geolocalisable $geolocalisable
* @return SpatialBuilder
*/
public function scopeNear(SpatialBuilder $query, Geolocalisable $geolocalisable): SpatialBuilder
{
return $query
->distanceSphereValue('location', $geolocalisable->position())
->distanceSphere('location', $geolocalisable->position(), $geolocalisable->radiusInMeter());
}
服务模式
1. 服务 belongsTo
一个地点
2. 服务 MorphTo
一个可注册
可注册模型
1. 没有 Registrable 模型。它是与多个模型的多态关系。在此示例中,您看到 "Information"
2.那些可注册模型morphOne
服务
很遗憾,Eloquent 无法完成您要求的操作。
预加载查询与初始查询完全分开,因此检索到的任何值都不再可用。
您的选择要么是在您的约束中进行连接(您指出这可能不是高性能的),要么加载所有相关模型,然后 sort/filter 那些使用 PHP 的模型。
Query where the problem lies
\DB::enableQueryLog();
$place = Place::near($user)->with(['services','services.registrable' => function (MorphTo $query) {
$query->where('distance_of_visibility', '<', \DB::raw('places.distance'));
}])->find(22);
\DB::disableQueryLog();
dd(\DB::getQueryLog());
Generated queries
首先:查询将计算给定半径内的所有地点,并将计算的字段 distance 添加到 select
select *, st_distance_sphere(`location`, ST_GeomFromText(0.000000 00.000000)) as distance from `places` where st_distance_sphere(`location`, ST_GeomFromText(0.000000 00.000000)) <= 5000 and `places`.`id` = 22 limit 1
第二:with
将预加载 services
select * from `services` where `services`.`place_id` in (22)
最后:with
将尝试加载 registrable
但急切加载给出了 一个明显的错误,因为 places.distance 在此范围内不存在
select * from information where distance_of_visibility < places.distance and information.id in (5)
哪个抛出
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'places.distance' in 'where clause'
What am I trying to do
假设地点的计算字段距离 returns值55米
我只想在 distance_of_visibility 低于 55 米时(通过服务)加载信息.
所以我的问题是:我怎样才能让它以最有效的方式工作。计算距离需要一些查询时间。我会尽量避免加入 table + 重新计算。我想有一种方法可以访问 $query
之前的查询结果,但我不知道如何访问。
Context in case you need more information
放置模型
1.它使用https://github.com/grimzy/laravel-mysql-spatial
2.是hasMany
服务
3. 它包含一个将计算字段 distance 添加到 select:
/**
* Get the places near the user in a certain radius
* It also add the distance in the select statement
*
* @param SpatialBuilder $query
* @param Geolocalisable $geolocalisable
* @return SpatialBuilder
*/
public function scopeNear(SpatialBuilder $query, Geolocalisable $geolocalisable): SpatialBuilder
{
return $query
->distanceSphereValue('location', $geolocalisable->position())
->distanceSphere('location', $geolocalisable->position(), $geolocalisable->radiusInMeter());
}
服务模式
1. 服务 belongsTo
一个地点
2. 服务 MorphTo
一个可注册
可注册模型
1. 没有 Registrable 模型。它是与多个模型的多态关系。在此示例中,您看到 "Information"
2.那些可注册模型morphOne
服务
很遗憾,Eloquent 无法完成您要求的操作。
预加载查询与初始查询完全分开,因此检索到的任何值都不再可用。
您的选择要么是在您的约束中进行连接(您指出这可能不是高性能的),要么加载所有相关模型,然后 sort/filter 那些使用 PHP 的模型。