Postgres / Postgis支持点之间的距离计算,按给定点的距离排序等等,我试图滥用此设施:)
这是一个例子,只是为了说明我试图做的事情。
Width Height Thickness Hue Lightness Saturation
Item1 220 157 100 270 60 75
Item2 221 199 105 280 60 75
Item3 210 150 105 100 40 75
暂时忽略这些功能,要找到下表中与物理尺寸类似的近似匹配项:
SELECT * FROM items
ORDER BY sqrt((i1.width-i2.height)*(i1.width-i2.height)
+ (i1.width-i2.height)*(i1.width-i2.height)
+ (i1.thickness-i2.thickness)*(i1.thickness-i2.thickness))
(称之为pseudosql :))
我们可以将第4-6个属性视为维度,使得类似(或" close")颜色对于每个属性具有相似的值。我们可以通过添加这些字段来扩展上述查询。
现在,Postgres似乎能够通过索引来做一些相当不错的事情,这样可以大大加快上述查询速度,但数据类型似乎只有4个维度。
对于数百万条记录,计算的更好的解决方案是什么,更常见的是对10个尺度(或"尺寸")的记录相似性进行排序?
我目前正在考虑3个4D点并按3点的距离排序。
如果没有Postgis的话,我想问题是: -
在一个包含如下项目的表中,最快的方法是使用10个值输入(每个val字段一个)之间的差值之和进行排序,利用任何可能的,边界框,空间或其他索引等
例如
SELECT * FROM items
ORDER BY ((item_val1-xxxx)*(item_val1-xxxx)
* (item_val2-yyyy)*(item_val2-yyyy)
* ......
* (item_val10-zzzz)*(item_val10-zzzz))
其中xxxx,yyyy,zzzz表示前端应用程序中输入的值
item_name: string
item_val1: int
item_val2: int
item_val3: int
item_val4: int
item_val5: int
item_val6: int
item_val7: int
item_val8: int
item_val9: int
item_val10: int
非常感谢任何想法/替代方案。
答案 0 :(得分:4)
PostGIS非常适合GIS,但正如John B所指出的那样,cube extension非常适合用于 n - 维度Eucludian距离。
添加扩展名,并将具有GiST索引的新列添加到表中:
CREATE EXTENSION cube;
ALTER TABLE items ADD COLUMN point cube;
CREATE INDEX items_point_idx ON items USING gist (point);
填充point
字段,您可能希望通过将列乘以标量(2为2,0.5为一半等)来加权某些属性高于其他属性:
UPDATE items SET
point = cube(array[width, height, thickness, hue, lightness, saturation]);
现在使用自联接找到一些距离:
SELECT i1.id, i1.point, i2.id, i2.point, cube_distance(i1.point, i2.point)
FROM items i1, items i2
WHERE i1.id < i2.id
ORDER BY cube_distance(i1.point, i2.point);