You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在含子查询的距离计算查询中替换DB以返回Pub模型实例

解决Laravel中Haversine公式查询返回模型集合的问题

嘿,我来帮你搞定这个问题!你现在的函数用DB::select返回的是数组,想要拿到Pub模型实例的话,完全不需要在MySQL里声明变量,用Eloquent的查询构造器就能轻松解决,还能顺便修复SQL注入的风险(你原来直接拼接$distance的写法可是有安全隐患的哦)。

下面给你两种可行的方案:

方案一:直接用selectRaw添加计算字段

这种方法最简洁,直接在Eloquent查询里把距离计算作为字段返回,然后用having来过滤(因为WHERE不能直接用查询别名,HAVING可以):

public static function getByDistance($distance) {
    return Pub::selectRaw('*, (6371 * acos(cos(radians(40.4169473)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-3.7035285)) + sin(radians(40.4169473)) * sin(radians(latitude)))) AS distance')
        ->having('distance', '<', $distance)
        ->orderBy('distance')
        ->get();
}

这样返回的就是Illuminate\Database\Eloquent\Collection集合,每个元素都是Pub模型实例,你可以直接调用模型的属性和方法。

方案二:用子查询(fromSub)

如果你更习惯原来的子查询结构,Laravel提供了fromSub方法来把子查询作为临时表查询,外层依然用Pub模型来获取实例:

public static function getByDistance($distance) {
    // 先定义子查询,计算每个pub的距离
    $subquery = Pub::selectRaw('*, (6371 * acos(cos(radians(40.4169473)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-3.7035285)) + sin(radians(40.4169473)) * sin(radians(latitude)))) AS distance');
    
    // 从子查询结果中过滤并排序
    return Pub::fromSub($subquery, 'distances')
        ->where('distance', '<', $distance)
        ->orderBy('distance')
        ->get();
}

额外优化:让经纬度可配置(可选)

如果以后需要更换查询的中心点,你可以把经纬度做成参数传入,这样函数更灵活:

public static function getByDistance($distance, $centerLat = 40.4169473, $centerLng = -3.7035285) {
    return Pub::selectRaw(
        '*, (6371 * acos(cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) AS distance',
        [$centerLat, $centerLng, $centerLat]
    )
        ->having('distance', '<', $distance)
        ->orderBy('distance')
        ->get();
}

为什么原来用Pub会报错?

你之前直接把DB换成Pub报错,是因为原来的子查询写法没有用Eloquent的正确语法,而上面两种方案都是遵循Eloquent的查询规则,所以能正常返回模型实例。另外,注意我们全程用了参数绑定(Laravel会自动处理),避免了SQL注入风险,这比直接拼接字符串安全多了。

内容的提问来源于stack exchange,提问作者Ber Tsacianegu del Tepuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:26:28