Laravel 在对 collection 中的元素使用 forget 后重新索引 collection 进行分页

Laravel reindex collection for pagnation after having used forget on elements in collection

我有一个 collection 我得到了:

$clinics = Clinic::orderBy('name', 'asc')->paginate(30)->withQueryString();

假设最多有 5000 个项目。

现在我需要在 foreach($clinics as $key => $clinic) 循环中找出距离用户输入的地址超过 20 公里的诊所。

然后我计算如果在20公里以内,如果诊所在20公里以上,我就用$clinics->forget($key);

假设现在 collection 可能有 100 个项目。

到目前为止一切顺利(如果不是为了分页)。

但是现在当我进入分页的页面时,大部分页面都是空白的,分页说有 200 页,尽管只有 100 个项目,每页 30 个将导致 4页数。

我相信这是因为忘记了 collection 中的键,但分页仍然假定整个 collection。

如何在 laravel 中重新索引 collection 并且仍然可以使用分页?

我可以执行 scopeGetDistance,但我如何在查询中根据计算执行“获取此项目,并将此项目排除在外”?

我调查过这个:

更新:

以下代码在范围内:

public function scopeCloseTo($query, $lat, $long)
{
    return $query->whereRaw("
       ST_Distance_Sphere(
            point(long, lat),
            point(?, ?)
        ) * .000621371192 < 20
    ", [
        $long,
        $lat,
    ]);
}

这个returns错误:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for the right syntax 
to use near 'long, lat), point(?, ?) ) * .000621371192 < 20 ' at line 3 (SQL: select count(*)
 as aggregate from `clinics` where ST_Distance_Sphere( point(long, lat), point(11.816458, 55.451428) )
 * .000621371192 < 20 and `clinic_type_id` = 1)

当您根据纬度和经度计算距离时,您可以使用 ST_Distance_Sphere 函数直接在 mysql 中计算。你可以在这个博客中了解更多关于这个功能的信息(ST_Distance_Sphere Example).

在您的查询中,您将获取所有诊所,然后检查距离是否超过 20 公里,如果不超过 20 公里,那么您将从分页对象中删除它,因此它会产生问题。所以直接在 mysql 查询中进行验证,这样分页对象将始终提供所需的数据。下面是一个 eloquent 查询,它只会 returns 距离用户超过 20 公里的诊所。

Clinic::orderBy('name', 'asc')
    ->whereRaw(ST_Distance_Sphere(point('clinic_longitude', clinic_latitude), point($user_longitude, $user_latitude)) > 20000
    ->paginate(30)
    ->withQueryString();