【问题标题】:Geo Location Radius Search Using PHP and MySQL使用 PHP 和 MySQL 进行地理位置半径搜索
【发布时间】:2015-07-07 02:55:47
【问题描述】:

我正在开发一个工作门户,最终用户将在其中根据他们的位置和邻近半径搜索工作。目前,REST API 由 SLIM 和 MySQL 提供支持。 在 Jobs 表中,每一行都有纬度和经度。我在这里搜索过这个并偶然发现了Geo Distance search with MySQL

SELECT latitude, longitude, SQRT(
POW(69.1 * (latitude - $lat), 2) +
POW(69.1 * ($long - $long) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;


Where 

$lat =  User latitude

$long = User longitude

现在我还有另外两个问题。

  1. 如果只有 MySQL 查询就足够了,还是我必须使用它设置 Elastic Search?
  2. 是否有任何库或包可以帮助我解决这个特定问题?

如果您能对搜索性能提出任何有用的建议。

【问题讨论】:

    标签: php mysql elasticsearch geolocation


    【解决方案1】:
    SELECT latitude, longitude, SQRT(
    POW(69.1 * (latitude - $lat), 2) +
    POW(69.1 * ($long - longitude) * COS(latitude / 57.3), 2)) AS distance
    FROM TableName HAVING distance < 25 ORDER BY distance;
    

    在哪里

    $lat = 用户纬度

    $long = 用户经度

    【讨论】:

    • 这个查询是否足够,或者我必须在其中使用弹性搜索来快速处理?
    【解决方案2】:
    You have two option to find job by location 
    
    you required 
    1. Search users lat long
    2. Job users Posted Lat long (it may be job location or job posted user location from database)
    3. Query will be like - 
    SELECT zip,Round(((ACOS(SIN('$lat' * PI() / 180) * SIN(latitude * PI() / 180) + COS('$lat' * PI() / 180) * COS(latitude * PI() / 180) * COS(('$lon'-longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515),(2)) AS distance FROM Jobs Having distance <= 30 
    
    Else 
    1. You have to call all jobs data in single query.
    
         foreach($joblist as $job){
            $milesresult = $this->calculateDistance($user_lat,$user_lon,$job['latitude'],$jobr['longitude']);
            $miles = explode("-",$vendor['miles']);
             $vendor_max_miles = $miles[1];
            }
    
    2. PHP function for lat long
    
          function calculateDistance($lat1, $lon1, $lat2, $lon2, $unit) {
    
                $theta = $lon1 - $lon2;
    
                $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
    
                $dist = acos($dist);
    
                 $dist = rad2deg($dist);
    
                  $miles = $dist * 60 * 1.1515;
                $unit = strtoupper($unit);
    
                if ($unit == "K") {
                  return ($miles * 1.609344);
                } else if ($unit == "N") {
                    return ($miles * 0.8684);
                  } else {
                      return $miles;
                    }
            }
    

    【讨论】:

    • 好的好方法!我必须先计算距离,然后在查询中针对特定结果进行简单的算术运算。顺便说一句,你认为@jision 的答案更简单吗?
    • 还有一件事,我是否需要在其中实现 Elastic Search 以提高性能,它就足够了?
    • 第一个非常相似。如果您在查询中使用有子句,则运行查询将需要时间。如果您使用第二个,它将分配加载时间。是的,确保您实施了 Elastic Search,这将是加载和快速结果的另一种选择
    【解决方案3】:

    我已经和下面一起去了-

    SELECT id,
           name,
           lat,
           lng,
           ROUND((6371 * acos(
                           cos(radians($lat)) * cos(radians(lat)) * cos(radians(lng) - radians($lng)) +
                           sin(radians($lat)) * sin(radians(lat)))), (2)) AS distance
    FROM jobs
    HAVING distance < 50
    ORDER BY distance;
    

    我已经对数据进行了基准测试,发现这比 Mukesh 的答案略快,比 @jision 的答案好 2 倍。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多