2016-07-06 9 views
0

多くのプロパティを持つ2つのオブジェクトが類似しているかどうかを確認する最良の方法はありますか? LOCATION1、LOCATION2、LOCATION3、location4、...、postalCodeの、所有者、住民..データベース内の多くの文字列の類似性

彼らはすべてのPostgresのデータに格納されています。アドレス、同様に、10個のフィールドを持っている -

は、私は、オブジェクトを考えてみましょうjsonbタイプのベース。

新しいオブジェクトが入ってきたら、私は同じようなアドレスがあるかどうかを確認する必要があります。

この種のケースで最も一般的な手法は何ですか?

1つのアイデアはすべてのプロパティを連結し、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

関連する問題