一般的に言えば、JavaまたはScalaで記述されたストアド関数を使用することでこのタイプの問題を解決できます(PL / SQL、CまたはC ++を好む人もいます)。
PostgreSqlは(Javaベースの)ストアド関数をサポートしているため、SQLクエリでデータをフェッチし、ストアド関数に渡します。ストアド関数は距離を返すので、フィルター/ソートなどを行うことができます。
このような表に基づく
create table point(vector float8[]);
insert into point values('{0.0, 0.0, 0.0}');
insert into point values('{0.5, 0.5, 0.5}');
次のようなJava関数を使用します:
public class PlJava {
public final static double distance2(double[] v1, double[] v2) {
return Math.sqrt(Math.pow(v2[0] - v1[0], 2)
+ Math.pow(v2[1] - v1[1], 2) + Math.pow(v2[2] - v1[2], 2));
}
}
およびSQLでの関数宣言:
CREATE FUNCTION pljava.distance2(float8[], float8[])
RETURNS float8
AS 'PlJava.distance2'
IMMUTABLE
LANGUAGE java;
クエリは次のようになります:
select
point.*,
pljava.distance2(vector, '{1.0, 1.0, 1.0}') as dist
from
point
order by
dist;
その結果
vector | dist
---------------+-------------------
{0.5,0.5,0.5} | 0.866025403784439
{0,0,0} | 1.73205080756888
更新
保存された関数は、CおよびC++でも記述できます。 PostgreSqlへのインターフェースはC呼び出し規約を使用しているため、C++はより多くの労力を必要とします。 C++を使用した拡張性 を参照してください。