De manière générale, vous pouvez résoudre ce type de problèmes en utilisant une fonction stockée, écrite en Java ou Scala (certains préféreront PL/SQL, C ou C++).
PostgreSql prend en charge les fonctions stockées (basées sur Java), laissez donc la requête SQL récupérer les données et les transmettre à une fonction stockée. La fonction stockée renvoie la distance, vous pouvez donc filtrer/trier etc. dessus.
Basé sur un tableau comme celui-ci
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}');
avec une fonction Java comme celle-ci :
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));
}
}
et la déclaration de la fonction en SQL :
CREATE FUNCTION pljava.distance2(float8[], float8[])
RETURNS float8
AS 'PlJava.distance2'
IMMUTABLE
LANGUAGE java;
votre requête pourrait ressembler à ceci :
select
point.*,
pljava.distance2(vector, '{1.0, 1.0, 1.0}') as dist
from
point
order by
dist;
qui se traduit par
vector | dist
---------------+-------------------
{0.5,0.5,0.5} | 0.866025403784439
{0,0,0} | 1.73205080756888
Mettre à jour
Les fonctions stockées peuvent également être écrites en C et C++. C++ nécessite plus d'efforts, car l'interface avec PostgreSql utilise la convention d'appel C. Voir Utiliser C++ pour l'extensibilité