2016-07-06 50 views
0

檢查兩個具有多個屬性的對象是否相似的最佳方法是什麼?數據庫中很多字符串的相似性

可以說我有一個對象 - 地址,其中有10個領域,如:LOCATION1,LOCATION2,LOCATION3,LOCATION4,...,POSTALCODE,所有者,居住者..

它們都存儲在Postgres的數據基礎爲jsonb類型。

當新對象進來時,我需要檢查是否有任何類似的地址。

這種情況下最常用的技術是什麼?

一個想法是連接所有屬性並檢查levenshtein距離。

我現在沒有被綁定到任何特定的技術,要求是這些對象可能很多,它們必須存儲在某個地方。

+0

通常您會使用全文搜索索引,但我不確定這是否適用於Json數據。 –

回答

0

JSON和JSONB類型意味着具有不同含義標記的元素的數據。這通常意味着,這些不同的要素不能以完全相同的方式得到有效的處理,這進一步意味着一刀切的方法可能不會取得好的結果。

正如你所提到的那樣,Levenshtein距離是一種可能的方法,但大多數情況下它必須以某種方式加權定製到您的特定數據,甚至可能不足以滿足大多數實際情況數據集。

例如,考慮一些基本地址。匹配街道號碼本身毫無意義。同上街道名稱。真正的所有元素都是依賴的,只有從匹配的國家開始,通過州/省等進行下去時,「相似性」才具有真正的意義。簡單的權重無法捕捉到這種類型的關係。

解決方案是使用存儲過程來確定給定表中的行之間的相似性。雖然PL/pgSQL可以用於此(並且對於簡單的表格可以很好地工作),但當事情變得複雜時,可能需要深入挖掘PL/Python之類的東西。當然,這些存儲過程的效率與它們的寫法有很大的不同,但即使在大型數據庫中使用時,它們也可以很好地執行。

例如(而且也沒有足夠的信息在你的問題做出的東西,將直出在這裏工作,所以請把這樣的東西比僞要好一些,但不是徹底的測試PL/Python)的:

CREATE OR REPLACE FUNCTION compare_json_addresses(addr1 JSON, addr2 JSON) 
RETURNS INTEGER AS 
$$ 
BEGIN 
    import simplejson as json 
    a1, a2 = json.loads(addr1), json.loads(addr2) 
    similarity = 0 
    for unit in ('country', 'state', 'town', 'street', 'num'): 
     if a1[unit] != a2[unit]: 
      break 
     else: 
      similarity += 1 
    return similarity 
END; 
$$ 
LANGUAGE plpythonu STRICT IMMUTABLE; 

顯然你必須修改它以考慮你正在使用的各種附加位置字段,並弄清楚你希望它們如何關聯。

+0

感謝您的意見,實際上我決定使用elasticsearch來對數據進行索引,並通過主要字段對其進行過濾,並將它們與可能相似的字段進行匹配。所以它不知何故與你的答案相符。 – sandris