В моем проекте Rails у меня есть таблица с именем "items", где у каждого элемента есть свойство широты и долготы. Когда я получаю элементы для своего клиента, я получаю данные о долготе и широте текущего пользователя. Используя эти два набора координат, я хочу использовать функцию haversine и получить 100 результатов с наименьшим расстоянием haversine.
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
, но для этого потребуется использовать пользовательскую функцию в запросе, что я не уверен, как это сделать. Кроме того, что касается строк 7 и 8 запроса, я пытаюсь в предложении where быстро отфильтровать набор результатов на некотором разумном расстоянии, поэтому мне не нужно применять haversine ко всей таблице. Прямо сейчас у меня есть функция, определенная в синглтоне с именем DistanceService, но я предполагаю, что не могу использовать функции Ruby в запросе.
Когда я попытался добавить функцию haversine_distance
к контроллеру и вызвать ее следующим образом:
@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
. Это наводит меня на мысль, что сначала нужно как-то определить функцию в SQL с помощью некоторой миграции, но я не очень знаком с SQL и не знаю, как бы я это сделал с миграцией.
Мне также интересно, есть ли решение, которое бы поддерживало нумерацию страниц, поскольку, надеюсь, со временем оно станет требованием для моего проекта.
Спасибо.