2013-06-18 23 views
5

Tôi mới vào PostgreSQL và câu hỏi của tôi cũng tương tự như một ở đây: linkPostgreSQL để lặp qua các hàng và tìm trận đấu gần nhất sử dụng tùy chỉnh khoảng cách năng

Đối với ví dụ: Tôi có bảng sau:

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

một truy vấn mẫu mà đi một cái gì đó giống như

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

nên trở lại kết quả hàng trong một thời trang được sắp xếp, nơi tôi xác định "gần nhất" vecto r bằng cách sử dụng hàm Khoảng cách tùy chỉnh, ví dụ: calc_l2norm (độ chính xác kép [], độ chính xác kép []) trả về khoảng cách Euclide.

+0

Vì vậy, bằng cách gần nhất, bạn có nghĩa là khoảng cách tối thiểu giữa các đỉnh của vector tài liệu tham khảo cũng như của những người lưu trữ trong cơ sở dữ liệu? –

+0

có. tính toán khoảng cách giữa vector truy vấn và tất cả vectơ trong cơ sở dữ liệu. –

Trả lời

5

Nói chung bạn có thể giải quyết loại vấn đề này bằng cách sử dụng hàm được lưu trữ, được viết bằng Java hoặc Scala (một số có thể thích PL/SQL, C hoặc C++).

PostgreSql hỗ trợ (dựa trên Java) được lưu trữ chức năng, vì vậy hãy để truy vấn SQL tìm nạp dữ liệu và chuyển nó đến một hàm được lưu trữ. Hàm được lưu trữ trả về khoảng cách, vì vậy bạn có thể lọc/sắp xếp vv.

Dựa trên một bảng như thế này

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

với một chức năng Java như thế này:

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

và khai báo hàm trong SQL:

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

truy vấn của bạn có thể trông giống như này:

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

mà kết quả trong

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

Cập nhật

chức năng lưu trữ có thể được viết bằng C và C++ là tốt. C++ đòi hỏi nhiều nỗ lực hơn, bởi vì giao diện với PostgreSql đang sử dụng quy ước gọi C. Xem Using C++ for Extensibility

+0

ha, điều Java là thú vị (bạn có thể làm tương tự bằng cách sử dụng C++?). Tôi biết bạn có thể làm điều đó với C vì bạn có thể chọn 'C' làm ngôn ngữ khi viết định nghĩa hàm trong công cụ pgAdmin. Nhưng điều này rất hữu ích khi tôi định sử dụng các hàm Distance phức tạp hơn. –

+0

Có, cũng có thể trong C và C++; Tôi đã cập nhật câu trả lời. – Beryllium

Các vấn đề liên quan