求最近的一家门店

已知用户坐标和商户的坐标,从一组商家中筛选离用户位置最近的一个商家。求优雅的筛选方法。
用户坐标: lat, lng
商户 Model: Shop 包含 latitude,longitude 字段

orm
本帖已被设为精华帖!
本帖由系统于 3年前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
最佳答案

我理解的是计算直线距离 然后排序
shop 表应该也有经纬度两个字段
关于后续优化 应该就是加索引了
sql 应该是这样

SELECT *,SQRT(

    POW(111.2 * (lat - 40.0844020000), 2) +

    POW(111.2 * (116.3483150000 - lng) * COS(lat / 57.3), 2)) AS distance

FROM shop  HAVING distance < 25 ORDER BY distance;

参考文章

4年前 评论
osang (楼主) 4年前
讨论数量: 28

@勇敢的心 按照大佬的提示,自己尝试实现了一下,又学习到了新姿势:

代码已被折叠,点此展开
4年前 评论

用 Redis 实现是不是比较好

4年前 评论
osang (楼主) 4年前
勇敢的心 (作者) 4年前
osang (楼主) 4年前
osang (楼主) 4年前
勇敢的心 (作者) 4年前
osang (楼主) 4年前
勇敢的心 (作者) 4年前

我理解的是计算直线距离 然后排序
shop 表应该也有经纬度两个字段
关于后续优化 应该就是加索引了
sql 应该是这样

SELECT *,SQRT(

    POW(111.2 * (lat - 40.0844020000), 2) +

    POW(111.2 * (116.3483150000 - lng) * COS(lat / 57.3), 2)) AS distance

FROM shop  HAVING distance < 25 ORDER BY distance;

参考文章

4年前 评论
osang (楼主) 4年前

使用 Redis 的 GEO 模块,是支持地理位置计算的,适合很多场景:附近的商家等,灵活、高性能

4年前 评论
$lon = //经度
$lat = //纬度
$miles = //你的范围

$query = "SELECT *, 
( 3959 * acos( cos( radians('$lat') ) * 
cos( radians( latitude ) ) * 
cos( radians( longitude ) - 
radians('$lon') ) + 
sin( radians('$lat') ) * 
sin( radians( latitude ) ) ) ) 
AS distance FROM 表名 HAVING distance < '$miles' ORDER BY distance ASC LIMIT 0, 5"

tip: 要按公里而不是英里进行搜索,请将 3959 替换为 6371。

编辑:文档找半天 - -#,源于 Google。
sites.google.com/a/benamy.info/www...
mysql 浏览的适合有高亮,怎么实际显示就没有呢?

4年前 评论
LiamHao 4年前
peryiqiao (作者) 4年前
LiamHao 4年前

@勇敢的心 按照大佬的提示,自己尝试实现了一下,又学习到了新姿势:

代码已被折叠,点此展开
4年前 评论

@LiamHao 我也有所启发

$predis->georadius("city", "116.3948", "39.9029", 2, "km"); 
// array:1 [ 
//  0 => "天安门"    
//]
4年前 评论

用 redis 或者 es 都比 mysql 好吧

4年前 评论

Laravel 框架没办法同时使用多个 DB 驱动吧,如果可以的话一部分数据可以存到 mongodb 中,不然只能借助 redis 了

4年前 评论
LiamHao 4年前
LiamHao 4年前
osang (楼主) 4年前
codecodify (作者) 4年前

MYSQL 里有个 st_distance 函数:

SELECT `shops`.*,
       (st_distance(point(longitude, latitude), point(116.4600000000, 39.9200000000)) *111195) as distance
FROM `shops`
ORDER BY distance ASC;
4年前 评论

建议使用 Redis。

// 添加门店经纬度到 Redis
Redis::geoadd(自定义key, 门店经度, 门店纬度, 门店id);

// 从 Redis 中获取附近门店
Redis::geoRadius(自定义key, 用户经度, 用户纬度, 搜索半径, 'm', ['WITHDIST', 'ASC']);
4年前 评论

我以前的做法调用百度或者高德地图接口 计算距离,比自己计算的准确

3年前 评论