Вызов локальной функции в Postgres Query - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть функция, которая запрашивает мою базу данных, чтобы найти соседних пользователей.Тем не менее, моя база данных хранит долготу и широту пользователей, и для определения расстояния от пользователя мне нужно вызвать функцию (расстояние), чтобы проверить, каких пользователей вернуть в запросе.Есть ли способ сделать то, что у меня есть в коде (вызвать мою локальную функцию расстояния внутри строки запроса?)

exports.getNearby = function (longitude, latitude) {
var long1 = longitude;
var lat1 = latitude;
return new Promise(((resolve, reject) => {
    const queryString = `SELECT ${userModel.userId}
     FROM ${userModel.collectionName} where SELECT distance(${userLocationModel.latitude},
     ${userLocationModel.longitude}, ${lat1}, ${long1}) < 4`;
    db.query(queryString, (err, res) => {
        if (err) {
            logger.log('error', ` getUser - ${userIdArr} - ${err}`);
            reject(err);
        } else {
            resolve(res.rows[0]);
        }
    });
}));
};

function distance(lat1, lon1, lat2, lon2) {             //returns in km
  return 12742 * asin(sqrt(0.5 - cos((lat2 - lat1) * 0.01745329252)/2 
    + cos(lat1 * 0.01745329252) * cos(lat2 * 0.01745329252) * 
    (1 - cos((lon2 - lon1) * 0.01745329252)) / 2));
}

Функция, написанная в Postgres (как предложено @LaurenzAlbe)

CREATE FUNCTION distance(
lat1 double precision,
lng1 double precision,
lat2 double precision,
lng2 double precision
) RETURNS double precision AS 
'SELECT 12742
     * asin(
         |/ (
             0.5 - cos(
                 (lat2 - lat1) * 0.01745329252
             )/2 
             + cos(lat1 * 0.01745329252)
             * cos(lat2 * 0.01745329252)
             * (1 - cos(
                 (lon2 - lon1) * 0.01745329252
             )) / 2
         )
    )'
LANGUAGE sql IMMUTABLE;

1 Ответ

0 голосов
/ 26 февраля 2019

Если вы хотите использовать функцию в операторе SQL, вы должны определить ее внутри базы данных, используя CREATE FUNCTION.

Для такой функции я бы выбралLANGUAGE sql.

Рассматривали ли вы возможность использования расширения PostGIS, если хотите выполнять обработку географических данных внутри базы данных?Он предлагает все мыслимые функции из коробки.

Вот как ваша функция может выглядеть как функция SQL:

CREATE FUNCTION distance(
    lat1 double precision,
    lng1 double precision,
    lat2 double precision,
    lng2 double precision
) RETURNS double precision AS 
'SELECT 12742
         * asin(
             |/ (
                 0.5 - cos(
                     (lat2 - lat1) * 0.01745329252
                 )/2 
                 + cos(lat1 * 0.01745329252)
                 * cos(lat2 * 0.01745329252)
                 * (1 - cos(
                     (lon2 - lon1) * 0.01745329252
                 )) / 2
             )
        )'
    LANGUAGE sql IMMUTABLE;
...