2013-06-18 9 views
5

Jestem nowy na PostgreSQL i moje pytanie jest podobny do tego tutaj: linkPostgreSQL iterację wierszy i znaleźć najbliższy mecz przy użyciu niestandardowych Dystans funkcję

Np mam poniższej tabeli:

| id |  vector   | 
| 1 | { 1.43, 3.54, 5.55} | 
| 2 | { 4.46, 5.56, 4.55} | 
| 3 | { 7.48, 2.54, 4.55} | 
| 4 | { 2.44, 2.34, 4.55} | 

zapytanie próbka przechodzi coś

SELECT * FROM my_table WHERE vector CLOSEST('{1.23, 4.43, 4.63}') 

powinien zwrócić otrzymaną wierszy w uporządkowany sposób, gdzie określenia „najbliższy” vecto r za pomocą niestandardowej funkcji odległości, np. calc_l2norm (podwójna precyzja [], podwójna precyzja []), która zwraca odległość euklidesową.

+0

więc przez najbliższe, to znaczy minimalną odległość między czubkiem wektora odniesienia i że z tych przechowywanych w bazie danych? –

+0

tak. obliczyć odległość między wektorem zapytania a wszystkimi wektorami w bazie danych. –

Odpowiedz

5

Ogólnie rzecz biorąc można rozwiązać ten typ problemów za pomocą funkcji zapisanej w języku Java lub Scala (niektóre mogą preferować PL/SQL, C lub C++).

PostgreSql obsługuje funkcje zapisane w języku Java, więc niech zapytanie SQL pobiera dane i przekazuje je do zapisanej funkcji. Zapisana funkcja zwraca odległość, dzięki czemu można filtrować/sortować itp. Na niej.

Bazując na stole jak ten

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

z funkcją Java jak ten:

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

i deklaracji funkcji w SQL:

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

zapytanie może wyglądać to:

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

co skutkuje

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

Aktualizacji

Przechowywane funkcje mogą być napisane w języku C i C++, jak również. C++ wymaga więcej wysiłku, ponieważ interfejs do PostgreSql wykorzystuje konwencję wywoływania C. Zobacz Using C++ for Extensibility

+0

ha, Java jest interesująca (czy możesz zrobić to samo używając C++?). Wiem, że możesz to zrobić za pomocą C, ponieważ możesz wybrać "C" jako język podczas pisania definicji funkcji w narzędziu pgAdmin. Jest to jednak przydatne, ponieważ planuję użyć bardziej złożonych funkcji odległości. –

+0

Tak, jest to również możliwe w C i C++; Zaktualizowałem odpowiedź. – Beryllium

Powiązane problemy