我找到了解決方案,感謝EddyTheDove和Ohgodwhy。
因此,這是它:
\App\Model\User::whereNotIn('id', $ids)
->where('status', 1)
->whereHas('user_location', function($q) use ($radius, $coordinates) {
$q->isWithinMaxDistance($coordinates, $radius);
})->select('id', 'firstname')
->get();
在我UserLocation
型號我有這個局部範圍
public function scopeIsWithinMaxDistance($query, $coordinates, $radius = 5) {
$haversine = "(6371 * acos(cos(radians(" . $coordinates['latitude'] . "))
* cos(radians(`latitude`))
* cos(radians(`longitude`)
- radians(" . $coordinates['longitude'] . "))
+ sin(radians(" . $coordinates['latitude'] . "))
* sin(radians(`latitude`))))";
return $query->select('id', 'users_id', 'cities_id')
->selectRaw("{$haversine} AS distance")
->whereRaw("{$haversine} < ?", [$radius]);
}
原來答案由Ohgodwhy是在這裏: Haversine distance calculation between two points in Laravel
編輯
在MySQL存儲函數來執行它的另一種方式:
DELIMITER $$
DROP FUNCTION IF EXISTS haversine$$
CREATE FUNCTION haversine(
lat1 FLOAT, lon1 FLOAT,
lat2 FLOAT, lon2 FLOAT
) RETURNS FLOAT
NO SQL DETERMINISTIC
COMMENT 'Returns the distance in degrees on the Earth
between two known points of latitude and longitude'
BEGIN
RETURN DEGREES(ACOS(
COS(RADIANS(lat1)) *
COS(RADIANS(lat2)) *
COS(RADIANS(lon2) - RADIANS(lon1)) +
SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))
));
END$$
DELIMITER ;
我乘以111.045的結果轉換成公里。 (我不知道,這個值是正確的,我發現很多人值不遠處的這一個,所以如果有人有關於它的精確度,它可能是不錯的)
原創文章:https://www.plumislandmedia.net/mysql/stored-function-haversine-distance-computation/
然後使用雄辯:
\App\Model\User::whereNotIn('id', $ids)
->where('status', 1)
->whereHas('user_location', function($q) use ($radius, $coordinates) {
$q->whereRaw("111.045*haversine(latitude, longitude, '{$coordinates['latitude']}', '{$coordinates['longitude']}') <= " . $radius]);
})->select('id', 'firstname')
->get();
見:http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula – Serge
嗯,是謝謝你,但我已經有這個函數,我需要用MySQL來做這件事,因爲我有超過50000個用戶,在這種情況下,我應該得到所有這些用戶en計算距離並最終保持足夠接近的所有用戶,並且這可能需要太多資源.. – KeizerBridge
您應該真正使用空間索引,但是您可以直接在查詢中執行此操作,例如:http: //sackoverflow.com/questions/8994718/mysql-longitude-and-latitude-query-for-other-rows-within-x-mile-radius – Serge