3

Customer_Name、Address_Line_1、Post_Codeなどのフィールドを持つcustomerというカスタムオブジェクトがあります。

すべてのレコードを調べて、Customer_Nameの類似性を比較したいと思います(あいまい検索またはレーベンシュタイン距離に基づく)。類似度が特定のしきい値を上回っている、または下回っている場合、カスタムフィールド(Possible_Duplicate_Customer_ID__c)が更新され、重複の可能性が識別されます。

私はこれを実装することができましたが、2つの問題が発生しています:

1)。Salesforceのガバナー制限を超えています(スクリプトステートメントが多すぎます:200001)。これは、レーベンシュタイン距離アルゴリズムで必要とされる重いループが原因である可能性があります。2)。また、私がコミットしているリスト(newList)には、重複するIDが含まれています。

    private static List<Customer__c> newList = new List<Customer__c>();

webService static Integer findDupes() {

    Integer returnCount = 0;
    Double cost = 0;
    Integer COST_THRESHOLD = 5;

    Map<id,Customer__c> cMap = new Map<id,Customer__c>([
        select ID, Name, Customer_Name__c, Possible_Duplicate_Customer_ID__c 
        from Customer__c 
    ]);

    List<Customer__c> custList1 = cMap.values();        
    List<Customer__c> custList2 = custList1.clone();

    for (Customer__c cust1 :custList1) {
        for (Customer__c cust2 :custList2) {
            cost = LevenshteinDistance.computeLevenshteinDistance(
                    cust1.Customer_Name__c, cust2.Customer_Name__c);
                if(cost<COST_THRESHOLD && cost != 0) {
                    Customer__c c = new Customer__c(
                        id = cust2.Id, 
                        Possible_Duplicate_Customer_ID__c = cust1.Name
                    );
                    newList.add(c);
                }
                System.debug(cost+' edits to transform '
                        +cust1.Customer_Name__c+' to '+cust2.Customer_Name__c);
        }
    }

    returnCount = newList.size();

    update newList;        
    return returnCount;
}
4

3 に答える 3

2

getLevenshteinDistance 新しい方法を試しましたStringか?

ここで私の質問/アプローチも参照してください。同じ国の一致のみが同じ郵便番号または都市で返されることを主張することにより、最初の一致の数を抑えます。

于 2013-03-15T07:37:54.983 に答える
1

バッチ可能なインターフェイスを使用するクラス内でコードを実行することをお勧めします。これは、大量のデータを処理するのにはるかに適しています。Webサービスは入力を受け取らないため、スケジュールに従って1時間ごとにバッチを実行し、レコードにマークを付けて重複にフラグを付け、Webサービスでそれらを抽出できます。もちろん、リアルタイムにする必要がある場合は、代わりにこのループを最適化する必要があります。

更新リストの重複IDについては、更新に使用することcust2.Idでこれを説明する必要がありますが、顧客レコードがそれ自体と比較される場合を防ぐことはできないようです。これで修正されるはずです:

for (Customer__c cust1 :custList1) {
    for (Customer__c cust2 :custList2) {
        if (cust1.Id == cust2.Id) {
            continue;
        }
于 2012-04-18T23:23:45.123 に答える
0

Lev距離はあいまい一致に最適なツールですが、スクリプトステートメントの制限により、基本的にApexでは使用できません。私が使用しているバージョン(古いバージョンのApex Langから採用)を使用して、「0123456789」と「0246803579」を比較すると、700以上のスクリプトステートメントが必要になります。「実際のリソース使用量は、基本的に実行されるコードの行数とは相関関係がありません」と「ええ、しかし、「少数の」高度な開発者を煩わせると、ガバナー制限の実装中に手抜きをすることができます」と比較すると、60,000のスクリプトステートメントが必要です。少数の小さな比較を行っている場合、またはLevをスクリプトステートメントに適したものに書き直していない限り、プラットフォームで正当化するのは困難です。

私は、名前や短い単語の比較のためのSoundexや、派手な動的SOQL "LIKE"ステートメントなど、ApexのLevに安価なプロキシを使用することにしました。あなたがやろうとしていることがどういうわけかセット操作に蒸留されることができるなら、.containsはあなたに1つのスクリプト実行だけを要するので、それらはあなたにApexの大金のためにあなたに良い価値を与えます。

本当にたくさんのLevを実行する必要がある場合は、APIを使用するか、コードを書き直して行をよりコンパクトにする必要があります。ユースケースによっては、計算をブラウザにプッシュすることもオプションになる場合があります。

于 2012-04-23T07:25:23.940 に答える