我有一个数据库模型Position(lat,lon),其中包含latitudes和longitudes.
Position(lat,lon)
latitudes
longitudes.
我有一个名为的控制器操作show_close_by,该操作接收以度为单位的位置(my_lat, my_lon),公差(以千米为单位),并且应该返回数据库中处于公差范围内的位置列表。
show_close_by
(my_lat, my_lon)
为此,我使用haversine_distance公式来计算两个坐标之间的距离(以千米为单位)(在地球表面)(lat1, lon1, lat2, lon2)。
(lat1, lon1, lat2, lon2)
为了使查询更快,我在查询中写了整个haversine_distance公式:
haversine_distance
... WHERE 2*6371*asin(sqrt( power( sin( (:lat2-latitude)*pi()/(180*2) ) ,2) + cos(latitude*pi()/180)*cos(:lat2*pi()/180)*power(sin( (:lon2-longitude)*pi()/(180*2) ),2) )) < tolerance
查询的具体内容无关紧要。我的疑问是:是否有必要为数据库中的每个位置计算此庞大函数?我可以使用简单的功能过滤掉一些明显太远的位置吗?
好吧,我可以:使用嵌套的SQL查询,我可以查询数据库中大的“正方形”(经度/经度空间)内的位置,然后使用成本更高的三角函数过滤那些位置。类似于以下内容:
SELECT * FROM ( SELECT * FROM Positions WHERE lat-latitude < some_reasonable_upper_bound AND lon-longitude < same_upper_bound ) WHERE costly_haversine_distance < tolerance
最后,我的问题是:如何在Rails中实现这一点(而无需自己编写整个查询)?是否Positions.where(reasonable_upper_bound).where(costly_but_accurate_restriction)进行嵌套查询?如果没有,怎么办?
Positions.where(reasonable_upper_bound).where(costly_but_accurate_restriction)
非常感谢!
以下是进行嵌套查询的方法:
LineItem.where(product_id: Product.where(price: 50))
它发出以下请求:
SELECT "line_items".* FROM "line_items" WHERE "line_items"."product_id" IN (SELECT "products"."id" FROM "products" WHERE "products"."price" = 50)
请注意, 只会 id从products表格中提取。如果您尝试采用另一种方式连接两个实体,而这种魔力不合适,请使用Product.select(:some_field).where(...)。
id
products
Product.select(:some_field).where(...)