Azure Searchのフィールドマッピングでmetadata_storage_pathから生URLを取り出す方法

#はじめに
Azure BLOBストレージにpdfファイルなどをアップロードし、Azure Searchでインデクシングを行うと、ファイルの全文検索を行うことができます。これを応用して、ファイルの検索やファイルのダウンロードを行えるようなWebサイトの構築も可能です。サービス作成にあたり、筆者が一番はまってしまった所が、metadata_storage_path(Blobのリンクがbase64で変換されたデータ)の加工です。これを行わないと、生のURLを取り出せず、HTMLでハイパーリンクを設置することができません。コード側ではなく、Azure Search上でどうにか加工できないかと思い、トライした結果がこちらになります。MS公式ドキュメントに方法は書いてありますが、少し分かりづらいので、本記事にてまとめることにしました。

(公式: https://docs.microsoft.com/ja-jp/azure/search/search-indexer-field-mappings)

#Azure SearchとStorage Account(BLOB)のデプロイ
こちらの手順については、省略させて頂きます。本記事では、既にいくつかのファイルがインデクシングされ、フィールドが構成された状態であることを想定しています。

metadata_storage_pathの初期状態↓
<a href="https://imgur.com/uW4msrR"><img src="https://i.imgur.com/uW4msrR.png" title="source: imgur.com" /></a>

#フィールドの追加
生URLを格納するためのフィールドをAzure Searchで新たに追加してください。今回は例として「original_path」という名前のフィールドを「Retrievable」で作成しました。

<a href="https://imgur.com/JNfGFSd"><img src="https://i.imgur.com/JNfGFSd.png" title="source: imgur.com" /></a>

#フィールドマッピングの設定
REST APIを用いて、Azure Searchで作成されたインデックスのフィールドマッピングの設定を行います。今回APIを叩くツールとして、Postmanを使用します。

●初めに現在のフィールドマッピングの情報をGETしてきます。取得できた内容は全てメモ帳等にコピーしておいてください。

<a href="https://imgur.com/wSo6wNk"><img src="https://i.imgur.com/wSo6wNk.png" title="source: imgur.com" /></a>

```
GET https://[search service name].search.windows.net/indexers/[my indexer name]?api-version=[api-version]
Content-Type: application/json
api-key: [admin key]
```

●次に、decodeを行います。先ほどGETしたJSONを元に、以下のbodyをPUTしてください(伏字のところ等は適宜変えてください)。

```
{
"@odata.context": "https://XXXXX.search.windows.net/$metadata#indexers/$entity",
    "@odata.etag": "\"0x8D60D553BE516BF\"",
    "name": "YYYYY",
    "description": "",
    "dataSourceName": "ZZZZZ",
    "targetIndexName": "WWWWW",
    "schedule": null,
    "parameters": {
        "batchSize": null,
        "maxFailedItems": 0,
        "maxFailedItemsPerBatch": 0,
        "base64EncodeKeys": false,
        "configuration": {
            "dataToExtract": "contentAndMetadata"
        }
    },
   "fieldMappings" : [
   {
    "sourceFieldName" : "metadata_storage_path",
    "targetFieldName" : "metadata_storage_path",
    "mappingFunction" : { "name" : "base64Decode", "parameters" : { "useHttpServerUtilityUrlTokenDecode" : false } }
   }],
	
    "disabled": null
}
```

●次に、フィールドをフォークします。GETしたJSONを元に、以下のbodyをPUTしてください(伏字のところ等は適宜変えてください)。

```
{
"@odata.context": "https://XXXXX.search.windows.net/$metadata#indexers/$entity",
    "@odata.etag": "\"0x8D60D553BE516BF\"",
    "name": "YYYYY",
    "description": "",
    "dataSourceName": "ZZZZZ",
    "targetIndexName": "WWWWW",
    "schedule": null,
    "parameters": {
        "batchSize": null,
        "maxFailedItems": 0,
        "maxFailedItemsPerBatch": 0,
        "base64EncodeKeys": false,
        "configuration": {
            "dataToExtract": "contentAndMetadata"
        }
    },
   "fieldMappings" : [
	{ "sourceFieldName" : "metadata_storage_path", "mappingFunction" : { "name" : "base64Encode" } },
	{ "sourceFieldName" : "metadata_storage_path", "targetFieldName" : "original_path" }
	],
	
    "disabled": null
}
```

●更新されたフィールドマッピングの情報をGETしてみると、以下のようになっているかと思います。

```
{
"@odata.context": "https://XXXXX.search.windows.net/$metadata#indexers/$entity",
    "@odata.etag": "\"0x8D60E33753011E2\"",
    "name": "YYYYY",
    "description": "",
    "dataSourceName": "ZZZZZ",
    "targetIndexName": "WWWWW",
    "schedule": null,
    "parameters": {
        "batchSize": null,
        "maxFailedItems": 0,
        "maxFailedItemsPerBatch": 0,
        "base64EncodeKeys": false,
        "configuration": {
            "dataToExtract": "contentAndMetadata"
        }
    },
    "fieldMappings": [
        {
            "sourceFieldName": "metadata_storage_path",
            "targetFieldName": "metadata_storage_path",
            "mappingFunction": {
                "name": "base64Encode",
                "parameters": null
            }
        },
        {
            "sourceFieldName": "metadata_storage_path",
            "targetFieldName": "original_path",
            "mappingFunction": null
        }
    ],
    "disabled": null
}
```

#動作確認
フィールドマッピングの更新後、BLOB Storageにファイルをアップロードし、Azure Searchでインデクシングを行い、BlobのURLが取り出せていることを確認してみてください。

<a href="https://imgur.com/Y0CwmGG"><img src="https://i.imgur.com/Y0CwmGG.png" title="source: imgur.com" /></a>

#さいごに
本記事では、base64で変換されたデータであるmetadata_storage_pathの変換方法についてご紹介しました。登録したフィールドマッピングが反映されるのは、インデクシング時なので、新規にインデックスを作成するときなどは適用できない方法になっています。別の方法をご存知の方がいましたら、是非ともご教授頂けると幸いです。