我有大型 postgresql 数据库,包含文档。每个文档都表示为表中的一行。当新文档添加到数据库中时,我需要检查重复项。但我不能只select
用来找到完全匹配。两个文档可能略有不同,但仍然可以被视为重复,例如,如果一些次要字段不同而所有其他字段都相同。
我研究这个问题并找到解决这个问题的方法。可以MinHash
为每个文档计算签名并构建倒排索引,从数据库中查询相似的文档。但我不明白如何映射MinHash
到关系数据库。
据我了解,MinHash
签名是 N 个哈希的列表,其中 N 是许多属性。相似度计算如下:
# Given 2 signatures Sa and Sb containing N hashes.
# Calculate number of equal hashes Neq.
number_of_equal_hashes = 0
for ix in range(0, N):
if Sa[ix] == Sb[ix]:
number_of_equal_hashes += 1
similarity = float(number_of_equal_hashes)/N
如果您已经有两个签名,这很简单,问题是在数据库中找到相似度小于或等于某个值的所有文档(具有相应签名)。
例如,我可以创建具有多个列的表,如下所示:
| minhash0 | minhash1 | minhash3 | docid |
每minhashX
列对应于文档属性之一的 minhash,并且docid
是文档的标识符。我可以这样查询类似的记录:
select * from invidx
where ((case when minhash0=minhash2search0 then 1 else 0 end) +
(case when minhash1=minhash2search1 then 1 else 0 end) +
(case when minhash2=minhash2search2 then 1 else 0 end))/N > THRESHOLD
其中minhash2searchX
是新文档的 minhashes,而 THRESHOLD 是最小相似性。但是这种方法需要全扫描。有什么方法可以加速这个算法吗?