OCI Vision Serviceを使ってAIを搭載した画像検索が出来るアプリを作る

# はじめに

**OCI Vision**は、ディープラーニング・ベースの画像分析を大規模に実行するための**AIサービス**です。機械学習（ML）の専門知識がなくても、すぐに使える事前構築済みのモデルを利用して、アプリケーションに画像認識やテキスト認識等を**簡単に**組み込むことができます。

本記事では、LiveLabsの[Build AI-Powered Image Search into your Oracle APEX App](https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3811&clear=RR,180&session=111045147111657)を参考に、Oracle APEXで作成したソーシャル・メディア・アプリ（インスタグラムの様な写真を投稿することの出来るアプリ）に、OCI Visionの画像分類を使用して**AI搭載の検索機能**を実装します。


**【前提条件】**
- OCIのアカウントを作成済みであること
  （OCIのアカウントをお持ちでない場合は、[こちら](https://oracle-japan.github.io/ocitutorials/#%E6%BA%96%E5%82%99---oracle-cloud-%E3%81%AE%E7%84%A1%E6%96%99%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB%E3%82%92%E7%94%B3%E3%81%97%E8%BE%BC%E3%82%80)を参考にご作成下さい。）
- OCIの中に使用可能なコンパートメントが作成済みであること
  （コンパートメントの作成方法は[こちら](https://oracle-japan.github.io/ocitutorials/beginners/getting-started/)をご参照ください。）

**【所要時間】**
30分程

# 1. APEXでのアプリケーション開発
Oracle APEXは、**Oracle Databaseのための**ローコード・アプリケーション開発プラットフォームです。クラウドでもオンプレミスでも、**Oracle Database上であればどこでも**アプリケーションの開発・実装をすることが出来ます。

Oracle APEXはデータベースのライセンスに含まれているため、**Oracle Databaseのライセンスをお持ちの方は無料**でご使用出来るツールです。

エクセルやCSVファイルをインポートする事も可能で、インポートしたデータを基に**簡単に素早く**アプリケーション開発を行う事が出来ます。

## 1-1. APEX環境の準備
先ずは、APEXの開発環境を準備します。既にAPEXの開発環境をお持ちの方は[2. OCI APIキーの設定](https://qiita.com/marfujim/private/a9ebe698c865e20d4852#2-oci-api%E3%82%AD%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A)へスキップして下さい。

1. OCIコンソールにログインし、ホームページにある**クイックスタート**>**APEXを使用したAutonomous Databaseへのロー・コード・アプリケーションのデプロイ**をクリックします。
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/cb5704af-3dbf-f73d-7ef6-bf93cbc63d61.png)

2. **続行**をクリック
![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/7965cbc0-1957-2c9b-64ee-a4979a50ec3d.png)

3. 有効な管理権限を持つコンパートメントを選択します。
![1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/614d8ad6-7790-6267-fd62-8cea5ca685f5.png)

4. 作成するAutonomous DatabaseのADMIN用パスワードを入力します。
![1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/f9093ec6-7db2-b949-442f-acf4d57bd4bd.png)

5. APEXのデプロイが完了したら、**APEXの起動**をクリックします
![1-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/71457e47-177f-1195-ae3f-085fa23b4549.png)

6. 先程設定したデータベースのADMIN用パスワードを入力し、**管理にサインイン**をクリックします。
![1-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/08a04dd4-563f-33cb-10bd-78b178624ccf.png)

7. 次に、アプリケーションを作成する開発環境（ワークスペース）を作成します。**ワークスペースの作成**をクリックします。
![1-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/38dff270-e542-d3fc-5956-73f8b1e7cfbb.png)

8. **新規のスキーマ**をクリックします。
![1-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/fb62dc5e-6796-dbab-bff7-85ea0361c70d.png)

9. 立ち上がったワークスペース作成のポップアップウィンドウに以下を入力します。
    - **ワークスペース名** - 任意（本記事では**OCI_VISION**としています。APEXのワークスペースへのログイン時に使用するので忘れない様にご注意下さい。）
    - **ワークスペース・ユーザー名** - 任意（ご自分の名前等、お好きなユーザー名をご入力下さい。APEXのワークスペースへのログイン時に使用するので、忘れない様にご注意下さい。）
    - **ワークスペース・パスワード** - 任意（本記事では**Welcome12345#**としています。APEXのワークスペースへのログイン時に使用するので、忘れない様にご注意下さい。）
![1-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/374164d0-3407-4bd7-0efc-a75eba5227e2.png)

10. ワークスペースを作成すると、画面上部にメッセージが表示されます。ワークスペース名をクリックして、作成したワークスペースにログインします。
![1-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/cdc28126-7ac0-d5d4-13b0-810e76f89495.png)

11. 先程設定したワークスペース名、ワークスペース・ユーザー名、ワークスペース・パスワードを入力し、**サインイン**をクリックします。
![1-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/5ad2c785-0fef-7a58-999e-13c3e8afbe2c.png)

12. APEXのワークスペースにログインする事が出来ました。
![1-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/196c5ddd-bf45-cad0-70fe-a3c05e187a22.png)

これでAPEXの開発環境の準備が出来ました。



# 2. OCI APIキーの設定
REST APIを介してOracle APEXからOCIリソースにアクセスする為、OCI APIキーを生成し、Webクレデンシャルを作成します。

## 2-1. OCI APIキーの作成
1. OCIコンソールの右上にある人のアイコンをクリックし、**自分のプロファイル**（若しくは**ユーザー設定**）をクリックします。
![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/d0fe770c-ea9f-c4ce-8921-17a01ae5b089.png)

2. 下にスクロールし、画面左側に表示されているリソースの中からAPIキーをクリックします。**APIキーの追加**をクリックします。
![2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/2f374dde-8732-cc3c-f398-3ad9990e651b.png)

3. **APIキー・ペアの生成**を選び、**秘密キー**のダウンロードをクリックします（公開キーをダウンロードする必要はありません）。秘密キーをダウンロード後**追加**をクリックします。
![2-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/79cb2be7-5c72-3987-f2be-a637be80472d.png)
4. **構成ファイルのプレビュー**をコピーします。後程Webクレデンシャルを作成する際に使用するので、メモを取っておきます。メモを取ったら**閉じる**をクリックします。
![2-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/7fc1bfbd-eadd-0a0e-811e-321539433c17.png)


これでOCI APIキーを取得する事が出来ました。


## 2-2. Webクレデンシャルの作成
1. 先程作成したワークスペースに戻り、**アプリケーション・ビルダー**をクリックします。
![2-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/675a9469-53fc-56d7-c6ad-60324d2194d2.png)

2. OCIのサービスと連携させるため、Webクレデンシャルを作成します。**ワークスペース・ユーティリティ**をクリックします。
![2-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/3f0d6bee-e8b6-bedf-7716-e6ad1981d26a.png)

3. **Web資格証明**をクリックします。
![2-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/72f6d85e-1610-bec6-6472-ab9b7bbf99b0.png)

4. **作成**をクリックします。
![2-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/d24f2de9-1ce3-7b1f-943e-774702950126.png)

5. Web資格証明の入力欄に、以下を入力し、**作成**をクリックします。
    - **名前** - apex_ai_cred
    - **認証タイプ** - Oracle Cloud Infrastructure (OCI)
    - **OCIユーザーID** - ユーザーのOCID（OCI APIキー作成時にメモを取った構成ファイルのプレビューの中に記載があります。例：ocid1.user.oc1..aaaaaaaa******wj3v23yla）
    - **OCI秘密キー** - APIキーの作成時にダウンロードした秘密キー（APIキーの作成時にダウンロードした秘密キーをテキストエディタ等で開き、コピー＆ペーストします。）
    - **OCIテナンシID** - テナンシのOCID（OCI APIキー作成時にメモを取った構成ファイルのプレビューの中に記載があります。例：ocid1.tenancy.oc1..aaaaaaaaf7ush****cxx3qka）
    - **OCI公開キー・フィンガープリント** - フィンガープリントID（OCI APIキー作成時にメモを取った構成ファイルのプレビューの中に記載があります。例：a8:8e:c2:8b:fe:****:ff:4d:40）
![2-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/0817926d-ef64-cd47-12d6-682dac6f3805.png)


6. **アプリケーション・ビルダー**をクリックします。
![2-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/7ac3e02f-e470-6cb9-4fad-f716caf774a7.png)


# 3. アプリケーションのインポートと編集
事前作成済みのアプリケーションとそれに付随するオブジェクト（データベースの表）をインポートし、表を編集します。

## 3-1. 事前作成済みアプリケーションのインポート
1. LiveLabsの[Build a Social Media App Using Oracle APEX!](https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3620&clear=RR,180&session=100646565054866)を参考にして作成したソーシャル・メディア・アプリ上にAI搭載の検索機能を実装します。[こちら](https://github.com/marina-fujimoto/qiita/blob/main/f101.zip)をクリックし、「f101.zip」をダウンロードします。
![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/48298642-d750-8035-e434-104184b17b6d.png)

2. 事前に作成済みのアプリケーションを元にアプリケーションを作成するので、**インポート**をクリックします。
![3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/454e9299-8560-74af-bc5b-17f19fc1c5ed.png)

3. 先程ダウンロードした.zipファイルをドラッグアンドドロップし、**次**をクリックします。
![3-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/89af0f8f-e93c-c309-d18f-cfff3d528b89.png)


4. 設定事項はデフォルトのままにして、**アプリケーションのインストール**をクリックします。
![3-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a0f6d4ff-c040-d82d-a299-78466104021c.png)

5. **サポートするオブジェクトのインストール**をクリックし、アプリケーションで使用する表もインストールします。
![3-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a6465ed6-9f55-b05e-d614-e95aee2a1cd5.png)

6. アプリケーション、表のインストールが終わったら、**アプリケーションの編集**をクリックします。
![3-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/14eb5450-4894-2e1f-bcb8-f1dcb9bbb984.png)

## 3-2. データベースの表へ列を追加
1. 画面上部の**SQLワークショップ**>**オブジェクト・ブラウザ**をクリックします。
![3-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/996ab937-b4ee-e410-4cbf-aa0c348ce748.png)

2. 画面左側の**表**>**SM_POST**をクリックし、**列の追加**をクリックします。
![3-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a762e6a7-4624-e683-46a7-49dc6c25fe29.png)

3. 列の追加画面で以下の通りに入力し、**適用**をクリックします。
    - **列** - AI_OUTPUT
    - **データ型** - VARCHAR2
    - **長さ** - 1000
![3-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/765fb7e5-6ec6-598a-4015-14868405f8cf.png)

4. AI_OUTPUT列は、OCI Visionからのレスポンスを格納するための列となります。AI_OUTPUT列が追加されているのを確認したら、**アプリケーション・ビルダー**をクリックします。
![3-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/676798a9-1ced-110b-cc96-1d9ff2bee691.png)

5. 先程インポートしたAPEX Social Mediaという名前のアプリが表示されています。インポートされたアプリをクリックし、アプリケーションの編集ページへ移動します。
![3-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/6b5156ea-df97-5ad6-9b20-1e846ae2497a.png)



# 4. OCI VisionとOracle APEXの連携
「ユーザーがアプリに写真を投稿すると、OCI Vision APIが呼び出され、画像分類が行われる」ようにするため、OCI Visionとの接続に使用する**RESTデータ・ソース**と、そのRESTデータ・ソースを呼び出す**プロセス**を作成します。

## 4-1. RESTデータ・ソースの作成
1. RESTデータソースを作成します。**共有コンポーネント**をクリックします。
![4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/54b901a6-bbbb-2ccd-6c5b-c62919289903.png)

2. 左下の**データ・ソース**>**RESTデータ・ソース**をクリックします。
![4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/da77e6c2-926d-977a-7872-6755ac4167c9.png)

3. **作成**をクリックします。
![4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/54ef9338-36d5-e754-2eb6-0e1d49bae742.png)

4. **最初から**を選択し、**次**をクリックします。
![4-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a94a2fc9-d1fe-b985-c609-216f9c732aab.png)

5. 入力欄に以下を記入し、**次**をクリックします。
![4-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/f156c148-c6ba-7890-fbed-593e41e9c108.png)
    - **RESTデータ・ソース・タイプ** - Oracle Cloud Infrastructure (OCI)
    - **名前** - OCI Vision
    - **URLエンドポイント** - 各リージョンのAPIエンドポイント + /20220125/actions/analyzeImage（APIキーとADBインスタンスを作成したリージョンによって異なります。）

    :::note info
    **リージョンがAshburnの場合：**
    - URLエンドポイント = https://vision.aiservice.us-ashburn-1.oci.oraclecloud.com/20220125/actions/analyzeImage

    **リージョンがTokyoの場合：**
    - URLエンドポイント =https://vision.aiservice.ap-tokyo-1.oci.oraclecloud.com/20220125/actions/analyzeImage

    **その他のリージョンの場合：**
    - [こちら](https://docs.oracle.com/en-us/iaas/api/#/en/vision/20220125)から使用しているリージョンに対応するAPIエンドポイントをご確認下さい。APIエンドポイントの後ろに「/20220125/actions/analyzeImage」を付け忘れない様にご注意下さい。

6. 入力したURLエンドポイントがベースURLとサービスURLパスに分かれているのを確認し、**次**をクリックします。
![4-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/7c34f80b-f8aa-c90d-9fb8-5620cee22bdb.png)

7. 認証の画面で以下の通りに選択し、**RESTソースの手動作成**をクリックします。
    - **認証が必要です** - トグルをオン
    - **資格証明** - api_ai_cred
    ![4-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/0c0a0b55-437a-a2ef-c346-7d4598b057be.png)


8. 作成したRESTソース、**OCI Vision**をクリックします。
![4-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/afc20913-0e9e-d9f4-589a-fd521cf38e95.png)

9. 下へスクロールし、**操作**>**POST**を編集します。ペンのアイコンをクリックします。
![4-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/4b821ee9-2f23-a30c-bed9-436db3a594e5.png)

10. 操作の画面で以下を入力します。
    - **データベース操作** - マップされていません
    - **リクエスト本文テンプレート** - 以下のJSONをコピー＆ペースト（OCI VisionはJSONフォーマットのリクエストのみ受け付けます）
    ```
    {
         "compartmentId": "#COMPARTMENT_ID#",
         "image": {
         "source": "INLINE",
         "data": "#FILE_DATA#"
       },
      "features": [
      {
            "featureType": "#FEATURE_TYPE#",
            "maxResults": 5
         }
        ]
      }
    ```


11. **パラメータの追加**をクリックし、その後出てくるポップアップウィンドウを一度閉じます。その後、**本文との同期**が表示されるので、クリックします。
![4-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/63037768-ee9d-48bc-497f-6ef9ae3623d4.png)

12. ポップアップ画面が出てくるので、**OK**をクリックします。
![4-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/288b4f92-9eda-ae68-9f0a-7d40c1291a2d.png)

13. 3つの操作パラメータが作成されました。あと2つパラメータを追加したいので、**パラメータの追加**をクリックします。
![4-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/b02fbb58-b376-0d9a-ecf4-463f0d589260.png)

14. パラメータの編集画面で、以下の通りに入力します。このパラメータは、**レスポンスを記録しておく**ためのものです。入力し終えたら、**追加後、さらに追加**をクリックします。
    - **タイプ** - リクエストまたはレスポンス本文
    - **名前** - RESPONSE
    - **目的** - 出力
![4-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/c61d2657-3b7a-abc9-e5f6-b523163bba62.png)

15. パラメータの編集画面で、以下の通りに入力し、**パラメータの追加**をクリックします。
    - **タイプ** - HTTPヘッダー
    - **名前** - Content-Type
    - **目的** - 入力
    - **デフォルト値** - application/json	
    - **静的** - トグルをオン
    ![4-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/22b496f7-a33f-612c-c0e3-7373f513ff8f.png)

16. 今までの変更を保存します。**変更の保存**をクリックします。
![4-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/9926bda7-457c-de3d-0d3f-8773239763be.png)

## 4-2. RESTデータ・ソースを呼び出すプロセスを作成する
次に、先程作成したOCI VisionというRESTデータ・ソースを呼び出すプロセスをAPEXのページデザイナーで作成します。
1. **アプリケーションID**をクリックします。
![4-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/21a0461b-12c0-92a5-4ffd-1926e6a105a1.png)

2. 画面下部にある**Timeline**というページをクリックします。
![4-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/42ac329f-f99e-8c5d-b28d-7a2b63eebe48.png)

3. Timelineという名前のリージョンを右クリックし、**アイテムの作成**をクリックします。
![4-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/1bdcd03e-b0ba-29e5-5e32-c4aaaffc6b73.png)

4. 作成したアイテムを編集します。画面右側のプロパティ・エディタで以下の通り入力します。
    - **名前** - P1_RESPONSE
    - **タイプ** - 非表示
![4-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/d238981d-2432-4d35-132e-68e53d836946.png)

5. 次に、画面左側の**プロセス**タブへ移動します。プロセスを右クリックし、**プロセスの作成**をクリックします。
![4-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/3049b1d7-2dbd-50c9-e290-a94ea336abb4.png)

6. 作成したプロセスを編集し、ユーザーがアプリに写真を投稿するたびにこのプロセスが呼び出される様にします。画面右側のプロパティ・エディタで以下の通り入力します。
    - **識別**
        - **名前** - Analyze Image
        - **タイプ** - 実行チェーン
    - **設定**
        - **バックグラウンドで実行** - トグルをオン
![4-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/dbf7288e-8402-2480-7e00-9b523097ed6f.png)

7. 作成したAnalyze Imageというプロセスを右クリックし、**子プロセスの追加**をクリックします。
![4-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/2191d331-fa0d-bb13-fcfb-ffcb7157ba75.png)

8. 作成した子プロセスを編集し、RESTデータ・ソースを呼び出すプロセスにします。画面右側のプロパティ・エディタで以下の通り入力します。
    - **識別**
        - **名前** - Invoke REST Data Source
        - **タイプ** - APIの呼び出し
        - **実行チェーン** - Analyze Image
    - **設定**
        - **タイプ** - RESTソース
        - **RESTソース** - OCI Vision
        - **操作** - POST
![4-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/4054455b-86ca-f46f-b54a-4c1e6da194cc.png)

9. 左側のビューから**COMPARTMENT_ID**をクリックします。右側のプロパティ・エディタに以下を入力します。
![4-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/66f0e67e-0bd3-0284-d9ea-45774b25d680.png)
    - **値**
        - **タイプ** - 静的値
        - **静的値** - コンパートメントID

    :::note info
    **【コンパートメントID】**
    - **ルートコンパートメントを使用している場合**：OCI APIキー作成時にメモを取った構成ファイルのプレビューの中に記載があります
    - **それ以外のコンパートメントを使用している場合**：OCIコンソールのナビゲーションメニュー>アイデンティティとセキュリティ>コンパートメントから、使用しているコンパートメントのOCIDを探します

10. 画面左のビューから**FEATURE_TYPE**をクリックします。右側のプロパティ・エディタに以下を入力します。
    - **値**
        - **タイプ** - 静的値
        - **静的値** - IMAGE_CLASSIFICATION（本記事では画像分類のみを行うので、IMAGE_CLASSIFICATIONと設定します）
![4-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/dbfd96ce-d4c7-fdb3-48b3-bb1d1c85883e.png)

11. 左側のビューから**FILE_DATA**をクリックします。右側のプロパティ・エディタに以下を入力します。
    - **値**
        - **タイプ** - SQL問合せ（単一の値を返す）
        - **静的値** - 以下のSQLクエリをコピー＆ペースト（アップロードした画像ファイルを取得し、CLOBデータ型に変換するクエリです）
    ```
    select 
        replace(replace(apex_web_service.blob2clobbase64(file_blob),chr(10),''),chr(13),'')
    from SM_posts
    where ID = :P1_ID;
    ```
    入力すると、以下の様になります。
    ![4-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a87f7130-e595-68f7-1fb2-54f0ac529077.png)

12. 画面左のビューから**RESPONSE**をクリックします。右側のプロパティ・エディタに以下を入力します。
    - **パラメータ** 
        - **出力を無視** - トグルをオフ
    - **値**
        - **アイテム** - P1_RESPONSE
![4-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/7dd0503c-462b-ad40-9e55-9b93b9968f91.png)

13. 画面左のビューから、作成したAnalyze Imageというプロセスを右クリックし、**子プロセスの追加**をクリックします。
![4-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/1e3db660-0471-8eaa-0b09-373413da2be7.png)

14. 作成した子プロセスを編集します。画面右側のプロパティ・エディタで以下の通り入力します。
    - **識別**
        - **名前** - Parse the Response
    - **ソース**
        - **PL/SQLコード** - 以下のSQLクエリをコピー＆ペースト（OCI Visionが行った画像分類の結果を、SM_POST表のAI_OUTPUTに格納するクエリです）
        ```
        UPDATE SM_POSTS
        SET
        AI_OUTPUT = (
            SELECT
                LISTAGG(obj_name, ',') WITHIN GROUP(
                ORDER BY
                    obj_name
                )
            FROM
                JSON_TABLE ( :P1_RESPONSE, '$.labels[*]'
                    COLUMNS
                        obj_name VARCHAR2 ( 100 ) PATH '$.name[*]'
                )
          )
         WHERE
         ID = :P1_ID;
        ```
        ![4-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a8b6c236-5df0-8510-1d12-b3959ec73650.png)
15. これでプロセスの作成が終わりました。**保存**をクリックし、今までの変更を保存します。


## 4-3. AIを搭載した検索機能を実装する
1. **レンダリング・ビューにタブを切り替え**、After Logoを右クリックし、**アイテムの作成**をクリックします。
![4-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/cc8f7140-bdff-1287-b096-26ea4a1e99c8.png)


2. 画面右のプロパティ・エディタで以下の通りに入力します。
    - **識別**
        - **名前** - P1_AI_SEARCH
    - **設定**
        - **[Enter]を押すと送信** - トグルをオン
    - **外観**
        - **テンプレート** - Hidden
        - **幅** - 100
        - **値のプレースフォルダー** - 検索したい写真を表す言葉を入力してください
![4-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/19e95511-4a18-753e-f26a-922bed3d80c7.png)


3. **Timeline**リージョンをクリックし、画面右のプロパティ・エディタで以下を入力します。
    - **送信するページ・アイテム** - P1_AI_SEARCH
    - **SQL問合せ** - 以下のSQLクエリに変更（アップロードした投稿を全て表示するSQLクエリが記述されているので、検索機能を実装し投稿フィルタリングできるように、where句を追記します）
    ```
    select
    p.id,
    p.created_by AS user_name,
    p.post_comment AS comment_text,
    p.file_blob,
    p.file_mime,    
    apex_util.get_since(p.created) post_date,
    (
        select count(*) from SM_REACTIONS smr
        where smr.post_id=p.id
    ) as REACTIONS,
    (
        select 'user-has-liked' from SM_REACTIONS smr
        where smr.post_id=p.id and created_by=UPPER(:APP_USER)
    ) USER_REACTION_CSS
    from SM_POSTS p
    where (:P1_AI_SEARCH IS NOT NULL AND upper(ai_output) like upper('%'||:P1_AI_SEARCH||'%'))OR :P1_AI_SEARCH IS NULL
    order by p.created desc;
    ```
    変更が終わったら、右上にある**保存と実行**をクリックします。
    ![4-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/e91be8d3-7951-a9a7-0f49-c195f1067c5b.png)

4. アプリを実行すると、ログイン画面が表示されます。このログイン画面は、APEXでアプリケーションを開発するとデフォルトで実装される機能です。ワークスペースのユーザー名とパスワードを入力し、サインインします。
![4-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/35ec4c33-f8d8-a639-6c07-dba26233fed5.png)

5. サインインするとこの様な画面が表示されます。今はまだ写真をアップロードしていないので、何も表示されないままで大丈夫です。
![4-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/b7d73f7a-e8e9-99b7-d5a5-f4afed8db22b.png)

# 5. OCI Vision Serviceを試してみる
作成したソーシャル・メディア・アプリに写真を投稿し、AI搭載の画像検索機能を試してみます。
本記事では[こちら](https://www.pexels.com/ja-jp/)のサイトから、無料、かつロイヤリティフリーの写真をダウンロードし、使用しています。

1. 画面左上の投稿ボタンをクリックし、写真をアップロードします。
![5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/cb4efb16-71cd-44ac-d6a0-1b93c5be9829.png)

2. 写真をアップロード、コメントを入力したら、投稿ボタンをクリックし、写真を投稿します。
![5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/9c55e216-7b42-4fa1-81e9-8b2ad2f396ab.png)

3. この様に写真を投稿する事が出来ました。他にも写真を投稿してみます。
![5-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/5329c38c-6e14-e426-5755-e7d6a6617c00.png)
アプリケーションに他のユーザーも追加すれば、他のユーザーも投稿をすることが出来ます。
![5-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/c904281c-5805-76c6-7a5e-ec9b2a699f74.png)

5. 写真を何枚か投稿したら、投稿した写真を表す・関連する言葉を検索バーに入力し、検索してみます。試しに**dog**と入力し、検索してみます。投稿されている犬の写真が全て表示されました。（検索するワードは投稿した写真に合わせて変更して下さい。）
![5-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/14e0011d-aeea-ee6c-651b-7be037ca12c9.png)

6. 次に、**flower**と入力し、検索してみます。投稿されている花の写真が全て表示されました。（検索するワードは投稿した写真に合わせて変更して下さい。）
![5-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/57873033-b777-440c-a78b-5650c8acd82c.png)


この様に、写真を検索する事が出来ました。

:::note info
**【補足】**
表のAI_OUTPUT列に、各画像に紐ずくワード（OCI Visionが行った画像分類の結果）が格納されています。
画像ごとにそれぞれ5つずつワードがタグ付けされており、その内いずれかのワードで検索すると画像が検索結果として表示されるようになります。
![5-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/f4d85990-3b1f-af33-0dee-a9e65d1c5702.png)

:::

# 参考資料
- [Build AI-Powered Image Search into your Oracle APEX App](https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3811&clear=RR,180&session=111045147111657)
- [Empowering Search with OCI Vision in Oracle APEX](https://blogs.oracle.com/apex/post/empowering-search-with-oci-vision-in-oracle-apex)
- [Step-by-Step Guide: Integrate AI Powered Image Search into an APEX app](https://www.youtube.com/watch?v=0XlJC3HxA1Y) 
- [Build a Social Media App Using Oracle APEX!](https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3620&clear=RR,180&session=100646565054866)
- [Oracle APEXでソーシャル・メディア・アプリケーションを作成しよう! - ハンズオン手順](https://speakerdeck.com/oracle4engineer/oracle-apexdesosiyarumedeiaapurikesiyonwozuo-cheng-siyou)
- [Vision API](https://docs.oracle.com/en-us/iaas/api/#/en/vision/20220125)
- [AnalyzeImage](https://docs.oracle.com/en-us/iaas/api/#/en/vision/20220125/AnalyzeImageResult/AnalyzeImage)