MatchRecordってなんだろう

久々にSalesforceを使うにあたり改めてApex開発者ガイドを見てみると「MatchRecordクラス」というものがあったので、ちょっと調べて見た

# MatchRecordクラスとは
公式ドキュメントには次のように書いてある
>一致ルールで検出された重複レコードを表します。

一致ルールは「設定」>「Data.com管理」>「重複管理」>「一致ルール」で設定できるルールで、「どんな条件を満たしている場合は重複とみなすのか」を独自で設定できる。
デフォルトでは3つくらいがあらかじめ設定されている。

メソッドは公式ドキュメントに次のように書いてある

|メソッド名|説明|
|:------|:----------|
|getAdditionalInformation()|一致レコードに関するその他の情報を返します。たとえば、matchGrade は、一致レコードに含まれる D&B 項目のデータ品質を表します。|
|getFieldDiffs()|すべての一致ルール項目と、重複およびその一致レコードについての各項目値の比較結果を返します。|
|getMatchConfidence()|一致レコードのデータと要求内のデータの類似度のランキングを返します。要求で指定された minMatchConfidence の値以上である必要があります。使用されていない場合は -1 を返します。|
|getRecord()|重複の項目と項目値を返します。|

簡単に試せそうなのはgetFieldDiffs()かな。とりあえず試してみる。

...と思ってサンプルコードを見てみると、

```java
public PageReference save() {

    // Optionally, set DML options here, use “DML” instead of “false”
    //   in the insert()
    // Database.DMLOptions dml = new Database.DMLOptions();
    // dml.DuplicateRuleHeader.allowSave = true;
    // dml.DuplicateRuleHeader.runAsCurrentUser = true;
    Database.SaveResult saveResult = Database.insert(contact, false);

    if (!saveResult.isSuccess()) {
      for (Database.Error error : saveResult.getErrors()) {
        // If there are duplicates, an error occurs
        // Process only duplicates and not other errors
        //   (e.g., validation errors)
        if (error instanceof Database.DuplicateError) {
          // Handle the duplicate error by first casting it as a
          //   DuplicateError class
          // This lets you use methods of that class
          //  (e.g., getDuplicateResult())
          Database.DuplicateError duplicateError = (Database.DuplicateError)error;
          Datacloud.DuplicateResult duplicateResult =  duplicateError.getDuplicateResult();

          // Display duplicate error message as defined in the duplicate rule
          ApexPages.Message errorMessage = new ApexPages.Message(
            ApexPages.Severity.ERROR, 'Duplicate Error: ' +
            duplicateResult.getErrorMessage());
          ApexPages.addMessage(errorMessage);

          // Get duplicate records
          this.duplicateRecords = new List<sObject>();

          // Return only match results of matching rules that
          //  find duplicate records
          Datacloud.MatchResult[] matchResults =
            duplicateResult.getMatchResults();

          // Just grab first match result (which contains the
          //   duplicate record found and other match info)
          Datacloud.MatchResult matchResult = matchResults[0];

          Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();

          // Add matched record to the duplicate records variable
          for (Datacloud.MatchRecord matchRecord : matchRecords) {
            System.debug('MatchRecord: ' + matchRecord.getRecord());
            this.duplicateRecords.add(matchRecord.getRecord());
          }
          this.hasDuplicateResult = !this.duplicateRecords.isEmpty();
        }
      }

      //If there’s a duplicate record, stay on the page
      return null;
    }
```

`Database.DuplicateError`から`Datacloud.DuplicateResult`を使用して`Datacloud.MatchRecord`を取得している。
重複ルールを使用する必要がある（当たり前か）。

とりあえずサンプルコードのなかでDebug文をいれて結果をみてみる。

取引先責任者のサンプルデータとして「Frank Edna」があったので、それに重複ルールで引っかかるようなデータを作成して、保存ボタンを押してみると次のようなログが出た。

```
18:41:43:205 USER_DEBUG [78]|DEBUG|差分：(Datacloud.FieldDiff[getDifference=Same;getName=Account;],
 Datacloud.FieldDiff[getDifference=Different;getName=Email;],
 Datacloud.FieldDiff[getDifference=Same;getName=FirstName;],
 Datacloud.FieldDiff[getDifference=Null;getName=Phone;],
 Datacloud.FieldDiff[getDifference=Null;getName=MailingPostalCode;],
 Datacloud.FieldDiff[getDifference=Same;getName=Title;],
 Datacloud.FieldDiff[getDifference=Null;getName=MailingCity;],
 Datacloud.FieldDiff[getDifference=Same;getName=LastName;],
 Datacloud.FieldDiff[getDifference=Null;getName=MailingStreet;])
```

この場合だと

- `getDifference=Null`：値が入っていない
- `getDifference=Same`：同じ値
- `getDifference=Different`：異なる値

となっている。