Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用自定义距离度量在postgreSQL中实现KNN的最佳方法是什么?_Postgresql_Indexing_Distance_Knn_Gist - Fatal编程技术网

使用自定义距离度量在postgreSQL中实现KNN的最佳方法是什么?

使用自定义距离度量在postgreSQL中实现KNN的最佳方法是什么?,postgresql,indexing,distance,knn,gist,Postgresql,Indexing,Distance,Knn,Gist,让我解释一下我的问题。 我有一张这种形状的桌子: +----+------+-----------+-----------+ | ID | A | B | W | +----+------+-----------+-----------+ | 1 | 534 | [a,b,c] | [4,6,2] | | 2 | 534 | [a,b,d,e] | [6,3,6,2] | | … | … | … | …

让我解释一下我的问题。 我有一张这种形状的桌子:

+----+------+-----------+-----------+
| ID |  A   |     B     |     W     |
+----+------+-----------+-----------+
| 1  | 534  | [a,b,c]   | [4,6,2]   |
| 2  | 534  | [a,b,d,e] | [6,3,6,2] |
| …  | …    | …         | …         |
| 54 | 667  | [a,b,r,e] | [4,6,2,3] |
| 55 | 8789 | [d]       | [9]       |
| 56 | 8789 | [a,b,d]   | [7,2,3]   |
| 57 | 8789 | [d,e,f,g] | [4,2,2,8] |
| …  | …    | …         | …         |
+----+------+-----------+-----------+
我需要执行的查询如下:给定一个具有A、B和W值的输入(例如A=8789;B=[A,B];W=[3,2]),我需要在表中找到在A上具有相同值的“最近”行

我已经定义了自定义距离函数。 天真的方法类似于(给定示例中的输入):

在我的理解中,这是一个经典的KNN问题,我意识到有些东西已经存在:

我只是不知道哪个是最好的指标。
谢谢。

我认为您需要将B和W打包到一个列中(可能使用函数索引来动态地完成),以便对它们使用KNN GiST。此外,您的数据似乎没有进行空间划分(但没有看到dist_函数的细节,谁知道呢?),因此spgist似乎不太可能。假设dist_函数是欧几里德函数或类似的函数。因此,B列表示元素,W列表示元素的权重或值。当在两个元素不相同的集合之间计算dist_函数时,这些元素加上W=0。例如,dist_函数([a,b],[3,2],[a,b,d],[7,2,3])等于dist_函数([a,b,d],[3,2,0],[a,b,d],[7,2,3])。我认为您可以这样做(在一个组合列上),但必须编写大量的C代码。此外,我怀疑它实际上效率不高,可能比seq扫描要慢。当您必须动态地确定哪些维度存在时,很难排除树的整个分支。但是dist_函数已经考虑了哪些维度存在,哪些维度不存在。它是合理的,并且在每一对B,W之间工作。它在运行时可能定义得很好,但在索引构造时仍然是动态的,不是吗?我想你可以说它是固定在无限维上的,几乎所有的维都是零。但我不认为这会带来任何效率。我可能是错的,但这似乎不太可能。我认为您需要将B和W打包到一个列中(可能使用函数索引来动态地实现),以便对它们使用KNN GiST。此外,您的数据似乎没有进行空间划分(但没有看到dist_函数的细节,谁知道呢?),因此spgist似乎不太可能。假设dist_函数是欧几里德函数或类似的函数。因此,B列表示元素,W列表示元素的权重或值。当在两个元素不相同的集合之间计算dist_函数时,这些元素加上W=0。例如,dist_函数([a,b],[3,2],[a,b,d],[7,2,3])等于dist_函数([a,b,d],[3,2,0],[a,b,d],[7,2,3])。我认为您可以这样做(在一个组合列上),但必须编写大量的C代码。此外,我怀疑它实际上效率不高,可能比seq扫描要慢。当您必须动态地确定哪些维度存在时,很难排除树的整个分支。但是dist_函数已经考虑了哪些维度存在,哪些维度不存在。它是合理的,并且在每一对B,W之间工作。它在运行时可能定义得很好,但在索引构造时仍然是动态的,不是吗?我想你可以说它是固定在无限维上的,几乎所有的维都是零。但我不认为这会带来任何效率。我可能错了,但这似乎不太可能。
SELECT * from my_table T, dist_function(T.B,T.W,ARRAY[a,b],ARRAY[3,2]) as dist 
WHERE T.A = 8789
ORDER BY dist ASC
LIMIT 7