在 MySQL 中调用一个函数来过滤掉用户当前位置附近的餐馆
Posted
技术标签:
【中文标题】在 MySQL 中调用一个函数来过滤掉用户当前位置附近的餐馆【英文标题】:Call a function in MySQL to filter out the restaurants which are near to the user's current location 【发布时间】:2021-08-23 05:30:39 【问题描述】:需要什么?
我想获取用户当前位置附近的所有餐厅(10KM 范围内)。
说明
我有一个用户表user(Id, Name, Address)
,这里的地址是一个lat, long
字符串。例如20,21
.
第二张表是restaurant(Id, Name, Address)
,地址格式同上。
在前端,我获取用户的当前位置,然后发送到 API,在 API 中,我有一个从 mysql 调用以下查询的函数:
const getAllRestaurants = async (currentAddress: string): Promise<Array<Restaurant>> =>
// query restaurants (using typeorm which will generate something like this)
const rests = "SELECT * FROM restaurant LIMIT 0, 10";
const restsToReturn = [];
// got the restaurants, now filter on based of address
for (const rest of rests)
// call "isRestaurantInRange" which will return true if the restaurant is user's range
if (isRestaurantInRange(rest.Address, currentAddress))
restsToReturn.push(rest);
return restsToReturn;
缺点:
很慢。 分页无法按预期工作,因为如果 10 个中有 2 个在用户的范围内,那么我们必须手动加载下一个数据并检查相同的条件,直到达到 10 个。 这是一种肮脏的方法。我的期望:
isRestaurantInRange
可以保存在数据库(MySQL)中吗?这样当我请求函数在数据库级别运行并返回预期结果时,无需手动过滤?我不是 MySQL 专家,但据我所知,存储过程不会工作。虽然,这种方法有一个警告。即我无法调用 Google Maps Distance API 来获得两点之间的准确距离,因此需要一个可以使用 google API 的解决方案。
如果您知道基于 TypeORM 的解决方案,那也是可以接受的。
【问题讨论】:
你应该在mysql而不是你的客户端过滤结果,也不要一次选择所有。 这就是问题,如何在 MYSQL 上进行过滤?像你能运行我在 MySQL 中运行的过滤功能吗? ***.com/questions/42799118/… 。您还可以使用 mysqlsCREATE FUNCTION
在数据库中创建可调用函数。
但是如果我想调用谷歌的 API 来得到两点之间的准确距离呢?
这能回答你的问题吗? Find nearest latitude/longitude with an SQL query
【参考方案1】:
如果您在 InnoDB 中使用 SPATIAL 索引,则需要 MySQL 5.7.6(或更高版本)才能获得SP_Distance_Sphere()
。
将实际的 POINT 存储在表中;也就是说,不要即时计算它们,因为这可能会阻止索引的使用。
有关其他提示,请参阅http://mysql.rjweb.org/doc.php/find_nearest_in_mysql
拆分为 2 个表可能会有缺点。请提供SHOW CREATE TABLE
。
【讨论】:
【参考方案2】:好吧,有人建议坚持使用 MySQL 实现,这当然不会给出准确的结果。无论如何,我正在使用以下查询来获取它:
SELECT ST_Distance(ST_GeomFromText('POINT(31.4630941 74.3215482)', 4326 ), ST_GeomFromText('POINT(31.4780632 74.3125699)', 4326), 'kilometre') AS distance;
使用this 链接来验证 MySQL 函数是否提供了正确的两点之间的 STRAIGHT 距离。
This 是一篇关于 MySQL 空间数据的精彩文章。引用:
这是两个最常用的 SRS。 SRID 4326 是 GPS 坐标。
【讨论】:
以上是关于在 MySQL 中调用一个函数来过滤掉用户当前位置附近的餐馆的主要内容,如果未能解决你的问题,请参考以下文章