在 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/… 。您还可以使用 mysqls CREATE 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 中调用一个函数来过滤掉用户当前位置附近的餐馆的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 获取当前邮政编码 X 英里内的位置?

从大型数据集中过滤掉记录的最佳方法是什么

coredump时如何过滤掉共享内存

当用户改变当前位置时,核心位置框架的哪个函数被调用?

过滤掉OR的MySql注入

java怎么调用地图获取地理位置信息