背景と応用シナリオ
Salesforce は、企業の顧客関係管理 (CRM) の中核を担うプラットフォームです。その価値は、保持するデータの品質に大きく依存します。しかし、データの入力元が多岐にわたる(手動入力、Web-to-Lead、データインポート、API連携など)現代のビジネス環境において、重複データは避けがたい課題です。
重複したリードや取引先責任者は、営業担当者間の混乱を招き、マーケティング活動の効果を低下させ、カスタマーサポートの対応品質を損なう原因となります。例えば、同じ顧客に対して別々の営業担当者がアプローチしてしまったり、更新された連絡先情報が古いレコードに残ったままになったりするケースが考えられます。これは顧客体験の悪化に直結し、ひいてはビジネス機会の損失につながります。
Salesforce の Duplicate Management (重複管理) 機能は、このような問題を解決するために設計された、強力で柔軟なツールセットです。この機能は、レコードの作成時や編集時にリアルタイムで重複を検知し、ユーザーに警告を表示したり、作成をブロックしたりすることができます。さらに、既存のデータに対する一括での重複チェックも可能です。
技術アーキテクトとして、この標準機能を深く理解し、いつ、どのように宣言的な設定とプログラム的な介入を組み合わせるべきかを判断することが、データ品質を維持し、システム全体の健全性を高める上で極めて重要です。本記事では、Duplicate Management の仕組みから、Apex を用いた高度な制御方法までを技術的な観点から詳説します。
原理説明
Salesforce の Duplicate Management は、主に2つのコンポーネントで構成されています。Matching Rule (一致ルール) と Duplicate Rule (重複ルール) です。これらが連携して、重複の定義と、重複が検出された際の挙動を決定します。
1. Matching Rule (一致ルール)
Matching Rule は、「何をもって重複と見なすか」を定義するルールです。例えば、「取引先責任者オブジェクトにおいて、姓、名、およびメールアドレスが完全に一致する場合」といった条件を設定します。
- 項目の一致: どの項目を比較対象とするかを指定します。
- 一致条件: 「完全一致」や「あいまい(Fuzzy)一致」を選択できます。Fuzzy マッチングは、ニックネーム、タイプミス、略語などを考慮して類似性を判断する高度なアルゴリズムです。(例:「Bob」と「Robert」を同一と見なす)
- 標準ルールとカスタムルール: Salesforce は、一般的なシナリオに対応する標準の Matching Rule を提供していますが、ビジネス要件に応じて独自のカスタムルールを作成することも可能です。
2. Duplicate Rule (重複ルール)
Duplicate Rule は、特定の Matching Rule を使用して、実際に重複チェックを実行し、重複が検出された場合にどのようなアクションを起こすかを定義します。
- 対象オブジェクト: どのオブジェクト(例: リード、取引先)に対してルールを適用するかを指定します。
- アクション:
- 作成時のアクション (Action on Create): レコード新規作成時に重複が検出された場合の動作。「許可 (Allow)」または「ブロック (Block)」を選択できます。「許可」の場合、ユーザーに警告メッセージを表示し、オプションでレポートに記録します。
- 編集時のアクション (Action on Edit): レコード編集時に重複が検出された場合の動作。同様に「許可」または「ブロック」を選択できます。
- セキュリティ設定のバイパス: オプションで、レコードレベルのセキュリティを無視して組織全体のレコードと照合するかどうかを指定できます。これにより、ユーザーがアクセス権を持たないレコードとの重複も検出できます。
- アラートテキスト: ユーザーに表示される警告メッセージをカスタマイズできます。
ユーザーがレコードを保存しようとすると、Salesforce はそのオブジェクトで有効になっている Duplicate Rule を実行します。ルールは関連付けられた Matching Rule を使って既存データと照合し、一致が見つかれば定義されたアクション(警告またはブロック)をトリガーします。この一連のプロセスが、リアルタイムでのデータ品質維持を可能にしています。
サンプルコード
通常、Duplicate Management は宣言的に設定しますが、Apex を使用して DML 操作を実行する場合など、プログラムによる制御が必要になる場面があります。ここでは、Apex で重複ルールをどのように扱うかについて、公式ドキュメントに基づいたコード例を交えて解説します。
1. DML 操作における重複ルールの制御
Apex から `insert` や `update` を実行する際、標準の Duplicate Rule の動作を上書きしたい場合があります。例えば、特定のバッチ処理では重複を許可しつつもレポートには記録したい、といったケースです。この制御には `Database.DMLOptions` クラスとその内部クラスである `DuplicateRuleHeader` を使用します。
以下のコードは、取引先 (Account) を挿入する際に、重複ルールをバイパスせず、重複が検出された場合でもレコードの保存を許可し、その重複をレポートに記録するよう指定しています。
// DMLOptions を設定して、重複ルールの動作を制御します。 Database.DMLOptions dmlOptions = new Database.DMLOptions(); // DuplicateRuleHeader を取得し、詳細な設定を行います。 // allowSave を true に設定すると、重複が検出されても DmlException がスローされず、 // レコードの保存が許可されます。 dmlOptions.DuplicateRuleHeader.allowSave = true; // includeRecordDetails を true に設定すると、重複検出結果に // 一致したレコードの詳細情報が含まれるようになります。 // デフォルトは false です。 dmlOptions.DuplicateRuleHeader.includeRecordDetails = true; // runAsCurrentUser を true に設定すると、現在のユーザーの権限で // 重複ルールが実行されます。デフォルトは false で、システムモードで実行されます。 // これにより、ユーザーがアクセスできないレコードとの重複も検出されます。 dmlOptions.DuplicateRuleHeader.runAsCurrentUser = true; // 重複の可能性がある Account レコードを作成します。 // 組織に 'Burlington Textiles Corp of America' という名前の取引先が // 既に存在することを想定しています。 Account newAcct = new Account(Name='Burlington Textiles Corp of America'); // setOptions() メソッドを使用して、DML 操作に DMLOptions を適用します。 // この insert 操作は、データベースのトリガーや重複ルールを起動します。 Database.SaveResult saveResult = Database.insert(newAcct, dmlOptions); // DML 操作の結果を検証します。 if (saveResult.isSuccess()) { System.debug('Successfully inserted account. Account ID: ' + saveResult.getId()); } else { // isSuccess() が false を返した場合、エラーを処理します。 // allowSave が true の場合でも、他の理由(例:入力規則違反)で失敗する可能性があります。 for (Database.Error err : saveResult.getErrors()) { System.debug('The following error has occurred.'); System.debug(err.getStatusCode() + ': ' + err.getMessage()); System.debug('Account fields that affected this error: ' + err.getFields()); } } // 保存結果から重複情報を取得します。 // allowSave が true の場合、重複が検出されても isSuccess() は true を返しますが、 // getDuplicateResults() で重複の詳細を取得できます。 if (saveResult.getDuplicateResults() != null) { System.debug(saveResult.getDuplicateResults().size() + ' duplicate results found.'); for (Database.DuplicateResult duplicateResult : saveResult.getDuplicateResults()) { System.debug('Duplicate Rule: ' + duplicateResult.getDuplicateRule()); System.debug('Duplicate Rule Match Results: ' + duplicateResult.getMatchResults()); } }
このコードにより、Apex 経由のデータ投入時にも、標準のUI操作と同様の柔軟な重複管理が可能になります。特にデータ移行やバッチ処理において、エラーで処理を中断させるのではなく、後でレビューするために重複を記録しておきたい場合に非常に有効です。
2. Apex から能動的に重複を検索する
DML 操作を伴わずに、特定のレコードが既存データと重複しているかどうかをプログラムで確認したい場合があります。例えば、カスタムの Visualforce ページや Lightning Web Component で、ユーザーが入力した瞬間に重複チェックを行いたい場合などです。この目的には `Datacloud.FindDuplicates` クラスを使用します。
以下の例は、`Datacloud.FindDuplicates.findDuplicates()` メソッドを使用して、複数のリード (Lead) レコード候補に対する重複を検索する方法を示しています。
// 重複を検索したいSObjectのリストを作成します。 // IDが設定されていないため、これらは新規レコード候補と見なされます。 List<SObject> sObjectList = new List<SObject>(); sObjectList.add(new Lead(FirstName='John', LastName='Smith', Company='Acme')); sObjectList.add(new Lead(FirstName='Jane', LastName='Doe', Company='Salesforce')); try { // findDuplicates メソッドを呼び出して重複を検索します。 // このメソッドは Datacloud.FindDuplicatesResult のリストを返します。 // 各結果オブジェクトは、入力リストの各 SObject に対応します。 List<Datacloud.FindDuplicatesResult> results = Datacloud.FindDuplicates.findDuplicates(sObjectList); for (Datacloud.FindDuplicatesResult findDupeResult : results) { if (findDupeResult.isSuccess()) { System.debug('Successfully found duplicates.'); // getDuplicateRecords() は、重複と見なされたレコードのリストを返します。 List<Datacloud.DuplicateRecord> duplicateRecords = findDupeResult.getDuplicateRecords(); System.debug('Number of duplicate records found: ' + duplicateRecords.size()); for (Datacloud.DuplicateRecord duplicateRecord : duplicateRecords) { // getMatchResults() は、どのルールによって、どのように一致したかの詳細を返します。 List<Datacloud.MatchResult> matchResults = duplicateRecord.getMatchResults(); System.debug('Number of match results: ' + matchResults.size()); for (Datacloud.MatchResult matchResult : matchResults) { System.debug('Match Rule: ' + matchResult.getMatchRule()); } } } else { // isSuccess() が false の場合、エラーを取得します。 List<Datacloud.FindDuplicatesError> errors = findDupeResult.getErrors(); for(Datacloud.FindDuplicatesError error : errors) { System.debug('Error message: ' + error.getMessage()); } } } } catch (Exception e) { System.debug('An unexpected error has occurred: ' + e.getMessage()); }
この方法は、カスタムUIでより良いユーザーエクスペリエンスを提供したり、API経由で受け取ったデータを保存する前に事前検証を行ったりするシナリオで非常に強力です。
注意事項
Duplicate Management を実装・運用する際には、以下の点に注意が必要です。
- 権限:
- ユーザーが重複ルールのアラートを表示するには、「重複レコードを表示」の権限が必要です。
- 重複ジョブを実行したり、重複レコードセットを管理するには、「重複の管理」権限が必要です。
- Apex から `Datacloud.FindDuplicates` を使用する場合、実行ユーザーは対象オブジェクトへのアクセス権と、一致ルールで使用される項目への参照アクセス権が必要です。
- API とガバナ制限:
- `Datacloud.FindDuplicates.findDuplicates()` メソッドは、1トランザクションあたり最大5回まで呼び出すことができます。
- `findDuplicates()` に渡す `SObject` リストのサイズは、合計で100レコードまでです。
- DML 操作における重複ルールの評価は、CPU 時間などの標準的なガバナ制限を消費します。複雑な一致ルールや大量のデータは、パフォーマンスに影響を与える可能性があります。
- エラー処理:
- `Database.DMLOptions` で `allowSave = false`(デフォルト)に設定している場合、重複ルールがレコード作成をブロックすると `DmlException` がスローされます。`try-catch` ブロックでこの例外を適切に捕捉し、ユーザーに分かりやすいフィードバックを返す必要があります。例外メッセージには、どの重複ルールによってブロックされたかの情報が含まれます。
- `Datacloud.FindDuplicates` の結果オブジェクト (`FindDuplicatesResult`) の `isSuccess()` メソッドを必ず確認し、失敗した場合は `getErrors()` で原因を特定する処理を実装してください。
- 非同期処理:
- 大量の既存データに対する重複チェックは、UI から実行する Duplicate Job (重複ジョブ) を使用します。これは非同期で実行され、結果は `DuplicateRecordSet` および `DuplicateRecordItem` オブジェクトに保存されます。
- Duplicate Rule は、重複を検出した際に DuplicateDetectedEvent という Platform Event (プラットフォームイベント) を発行するように設定できます。このイベントを Apex Trigger やフローでサブスクライブすることで、重複検出時に非同期でカスタムロジック(例: 担当者への通知、関連レコードの更新)を実行でき、システムを疎結合に保つことができます。
まとめとベストプラクティス
Salesforce の Duplicate Management は、データ品質を維持するための不可欠な機能です。技術アーキテクトとしては、その能力を最大限に活用し、ビジネス要件に合わせて最適化する責任があります。
以下に、ベストプラクティスをまとめます。
- データガバナンス戦略から始める: ツールを導入する前に、組織として「何が重複か」「重複をどう扱うか」というルールを明確に定義することが最も重要です。この戦略が、Matching Rule や Duplicate Rule の設計の基盤となります。
- 宣言的アプローチを優先する: 可能な限り、標準の Matching Rule と Duplicate Rule を活用してください。コーディングなしで多くの一般的なユースケースに対応でき、メンテナンス性も高くなります。
- Fuzzy マッチングを賢く利用する: Fuzzy マッチングは強力ですが、意図しない一致を引き起こす可能性もあります。どの項目に適用するかを慎重に検討し、テストを十分に行ってから本番環境に展開してください。
- Apex は補完的に使用する: Apex は、カスタムUIでのリアルタイム検証、複雑なデータ連携ロジック、または標準の DML 動作の微調整が必要な場合に限定して使用します。`Database.DMLOptions` と `Datacloud.FindDuplicates` は、そのための強力なツールです。
- 定期的な監視とレビュー: 重複レポートやダッシュボードを作成し、データ品質を継続的に監視します。定期的に Duplicate Job を実行し、既存データのクレンジングを行うプロセスを確立してください。
- ユーザーへの教育: ツールを導入するだけでなく、なぜデータ品質が重要なのか、重複を避けるためにどのように入力すべきかをユーザーに教育することも、長期的な成功の鍵となります。
効果的な重複管理は、一度設定して終わりではありません。ビジネスの変化に合わせてルールを見直し、継続的に改善していくプロセスです。本記事で解説した宣言的な機能とプログラム的なアプローチを適切に組み合わせることで、信頼性の高い Salesforce 環境を構築し、その価値を最大化することができるでしょう。
コメント
コメントを投稿