在 Postgres 查询中调用本地函数
Call Local Function in Postgres Query
我有一个查询我的数据库以查找附近用户的功能。但是,我的数据库存储了用户的经度和纬度,为了找到与用户的距离,我需要调用一个函数(distance)来检查哪些用户在查询中 return 。有没有办法完成我在代码中的操作(在我的查询字符串中调用我的本地距离函数?)
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;
如果您想在 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;
我有一个查询我的数据库以查找附近用户的功能。但是,我的数据库存储了用户的经度和纬度,为了找到与用户的距离,我需要调用一个函数(distance)来检查哪些用户在查询中 return 。有没有办法完成我在代码中的操作(在我的查询字符串中调用我的本地距离函数?)
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;
如果您想在 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;