![](/img/trans.png)
[英]Directly accessing Active Storage using Active Record query interface
[英]Query N closest database entries using active record query interface
在我的 Rails 項目中,我有一個名為“items”的表,其中每個項目都有一個緯度和經度屬性。 當我為我的客戶檢索項目時,我會獲取當前用戶的經度和緯度。 使用這兩組坐標,我想使用半正弦 function 並以最小的半正弦距離獲取 100 個結果。
SQL 應如下所示:
SELECT
*,
haversine_distance(user_lat, user_long, item_lat, item_long) as distance
FROM
db.items
WHERE
item_lat < {user_lat} +1
AND item_lat > {user_lat}+1
AND ..
AND ..
ORDER BY distance DESC
LIMIT 100
但這需要在查詢中使用自定義 function ,我不知道該怎么做。 此外,關於查詢的第 7 行和第 8 行,我正在嘗試使用 where 子句在某個合理距離內快速過濾結果集,這樣我就不必將 hasrsine 應用於整個表。 現在,我在名為 DistanceService 的 singleton 中定義了 function,但我假設我不能在查詢中使用 Ruby 函數。
當我嘗試將 function haversine_distance
添加到 controller 並將其稱為:
@items = Item.select("items.*, haversine_distance(geo_long, geo_lat,
#{@current_user.geo_long}, #{@current_user.geo_lat}) AS distance")
.where(status: 'available', ....)
我遇到了FUNCTION ****_api_development.haversine_distance does not exist
。 這使我認為 function 應該首先通過一些遷移在 SQL 中以某種方式定義,但我對 Z9778840A0100CB30C982876741B5A2Z 不太熟悉,並且不會通過遷移來做到這一點。
我還想知道是否有支持分頁的解決方案,因為它有望最終成為我項目的要求。
謝謝。
在 Rails 中,您通過遷移定義數據庫函數:
class AddHaversineDistanceFunction < ActiveRecord::Migration
def up
execute <<~SQL
DELIMITER $$
DROP FUNCTION IF EXISTS haversine_distance$$
CREATE FUNCTION haversine_distance(
lat1 FLOAT, lon1 FLOAT,
lat2 FLOAT, lon2 FLOAT
) RETURNS FLOAT
NO SQL DETERMINISTIC
COMMENT 'Returns the distance in km
between two known points of latitude and longitude'
BEGIN
RETURN DEGREES(ACOS(
COS(RADIANS(lat1)) *
COS(RADIANS(lat2)) *
COS(RADIANS(lon2) - RADIANS(lon1)) +
SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))
)) * 111.045;
END$$
DELIMITER;
SQL
end
def down
execute "DROP FUNCTION IF EXISTS haversine_distance"
end
end
這里實際的 function 改編自Plum Island Media 。
但是您可能想查看提供此功能並使用更好公式的地理編碼器 gem 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.