我是PostgreSQL的新手,我的问题类似于这里的问题:link
例如,我有下表:
| 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} |
示例查询类似于
SELECT * FROM my_table WHERE vector CLOSEST('{1.23, 4.43, 4.63}')
应该以排序的方式返回结果行,其中我使用自定义距离函数确定“最接近”的向量,例如calc_l2norm(double precision [],double precision [])返回欧几里德距离。
答案 0 :(得分:5)
一般来说,你可以通过使用用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 ++编写。 C ++需要更多的努力,因为PostgreSql的接口使用C调用约定。见Using C++ for Extensibility
答案 1 :(得分:1)
PostgresQL具有最近邻索引功能
http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.1#K-Nearest-Neighbor_Indexing
它可以与PostgreSQL或PostGIS一起用于PostgreSQL的GIS扩展。参见