PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL per scorrere le righe e trovare la corrispondenza più vicina utilizzando la funzione di distanza personalizzata

In generale puoi risolvere questo tipo di problemi utilizzando una funzione memorizzata, scritta in Java o Scala (alcuni potrebbero preferire PL/SQL, C o C++).

PostgreSql supporta le funzioni memorizzate (basate su Java), quindi lascia che la query SQL recuperi i dati e li passi a una funzione memorizzata. La funzione memorizzata restituisce la distanza, quindi puoi filtrare/ordinare ecc. su di essa.

Basato su una tabella come questa

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}');

con una funzione Java come questa:

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));
    }
}

e la dichiarazione della funzione in SQL:

CREATE FUNCTION pljava.distance2(float8[], float8[])
  RETURNS float8
  AS 'PlJava.distance2'
  IMMUTABLE
  LANGUAGE java;

la tua richiesta potrebbe essere simile a questa:

select
    point.*, 
    pljava.distance2(vector, '{1.0, 1.0, 1.0}') as dist
  from
    point 
  order by
    dist;    

che si traduce in

    vector     |       dist  
---------------+-------------------  
 {0.5,0.5,0.5} | 0.866025403784439  
 {0,0,0}       |  1.73205080756888  

Aggiorna

Le funzioni memorizzate possono essere scritte anche in C e C++. C++ richiede uno sforzo maggiore, perché l'interfaccia per PostgreSql utilizza la convenzione di chiamata C. Vedi Utilizzo di C++ per l'estendibilità