基于第一个查询的热切加载

时间:2019-01-30 16:12:31

标签: mysql laravel eager-loading

  

查询问题所在

\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());
  

生成的查询

首先:查询将计算给定半径内的所有位置,并将计算出的字段距离添加到选择区域

 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,但急切加载会导致一个明显的错误,因为在此范围内不存在place.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'
  

我想做什么

比方说,位置的计算字段距离返回值 55

仅当 distance_of_visibility 在这些 55 米以下时,我才希望通过服务加载信息。

我的问题是:如何使它以最有效的方式工作。计算距离需要一些查询时间。我会尽量避免加入表+重新计算。我想有一种方法可以访问$query的以前的查询结果,但是我不知道怎么做。

  

需要更多信息的情况下

放置模型
 1.它使用https://github.com/grimzy/laravel-mysql-spatial
 2.是hasMany 服务
 3.它包含一个范围,该范围将计算出的字段距离添加到选择项:

    /**
     * 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 a 可注册

可注册模型
1.没有可注册模型。这是与多个模型的多态关系。在此示例中,您会看到“信息”
2.那些可注册模型morphOne 服务

1 个答案:

答案 0 :(得分:1)

不幸的是,您要求做的事情与Eloquent无关。

急切负载查询与初始查询完全分开,因此检索到的任何值都不再可用。

您的选择要么是在您的约束中进行联接(您指出可能不是有效的),要么是加载所有相关模型,然后使用PHP来对它们进行排序/过滤。