Node.js SDKを使ってImage Searchの類似検索を試す【検索編】

# 今回の目的（Node.js SDKを使って検索してみる）
前回、Image Searchの設定と画像取り込みまで終わりました。今回は、前回作ったImage Searchにプログラムでアクセスしてみようと思います。

## 実装環境の構築
今回はYarnを使ってでプロジェクト作成します。Yarnの開発環境が整っていない方はインストールを行っておいてください。（サンプルはYarnで作成していますが、npmでも構いません）

参考：Windows+Scoopの場合

``` yarnインストール
PS C:\Users\user> scoop install yarn
```

## Node.js プロジェクトの作成
それでは、Node.jsのプロジェクトを作ってみましょう

プロジェクトディレクトリの作成

```
PS C:\Users\user\Documents> mkdir node-sample


    Directory: C:\Users\user\Documents

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2020/05/19    15:59                node-sample

PS C:\Users\user\Documents> cd .\node-sample\
PS C:\Users\user\Documents\node-sample>
```

Node プロジェクトの作成

```
PS C:\Users\user\Documents\node-sample> yarn init
yarn init v1.22.4
question name (node-sample): alibaba-imagesearch-demo
question version (1.0.0):
question description: image search demo
question entry point (index.js):
question repository url:
question author: morozumi.h
question license (MIT):
question private:
success Saved package.json
Done in 30.04s.
PS C:\Users\user\Documents\node-sample>  

```

``` プロジェクト階層
PS C:\Users\user\Documents\node-sample> tree /F
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 9411-0B65 です
C:.
│  search01.jpg
│  index.js
│  package.json
│  yarn.lock
│
└─node_modules
    │  .yarn-integrity

PS C:\Users\user\Documents\node-sample>
```

### 依存関係の追加
Alibaba CloudのSDKを追加します。

``` 
PS C:\Users\user\Documents\node-sample> yarn add @alicloud/pop-core
yarn add v1.22.4
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
                                                                                                                        success Saved lockfile.
success Saved 10 new dependencies.
info Direct dependencies
└─ @alicloud/pop-core@1.7.9
info All dependencies
├─ @alicloud/pop-core@1.7.9
├─ @types/node@12.12.39
├─ bignumber.js@4.1.0
├─ debug@3.2.6
├─ httpx@2.2.3
├─ json-bigint@0.2.3
├─ kitx@1.3.0
├─ sax@1.2.4
├─ xml2js@0.4.23
└─ xmlbuilder@11.0.1
Done in 2.56s.
```

```
PS C:\Users\user\Documents\node-sample> yarn add @alicloud/imagesearch-2019-03-25
yarn add v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ @alicloud/imagesearch-2019-03-25@1.0.0
info All dependencies
└─ @alicloud/imagesearch-2019-03-25@1.0.0
Done in 2.38s.
```

```
PS C:\Users\user\Documents\node-sample> yarn add json-to-form-data
yarn add v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ json-to-form-data@1.0.0
info All dependencies
└─ json-to-form-data@1.0.0
Done in 1.78s.
PS C:\Users\user\Documents\node-sample> 

```

### 前回作成したImage Searchにアクセスする

アクセスキーとシークレットキーは前回作成したものを使用します。
また、リージョンとエンドポイントについては、以下の表から設定します。今回は日本（東京）を設定します。

| リージョン | エンドポイント |
|:-:|:-:|
| シンガポール  | imagesearch.ap-southeast-1.aliyuncs.com  |
| 中国 (香港)  | imagesearch.cn-hongkong.aliyuncs.com  |
| 日本 (東京)  | imagesearch.ap-northeast-1.aliyuncs.com  |
| オーストラリア (シドニー)  | imagesearch.ap-southeast-2.aliyuncs.com  |

``` index.js
const Client = require('@alicloud/imagesearch-2019-03-25')
const jtfd = require('json-to-form-data')
const fs = require('fs')

const accessKey = 'XXXXXXXXXXXXXXXX'
const seacretKey = 'YYYYYYYYYYYYYYY'

const client = new Client({
  accessKeyId : accessKey,
  accessKeySecret : seacretKey,
  endpoint : 'http://imagesearch.ap-northeast-1.aliyuncs.com',
  apiVersion : '2019-03-25'
})
const options = {
  method : 'POST',
  "Content-Type" : 'application/x-www-form-urlencoded; charset=UTF-8'
}

const picContent = fs.readFileSync('./search01.jpg').toString('base64')

// 画像の検索
const searchRequest = {
    InstanceName: 'itemsearch',
    PicContent: picContent
};

const searchData = jtfd(searchRequest)
client.searchImage(searchData, options).then(value => {
    console.log("Result: ", JSON.stringify(value,null,4));
}).catch(err => {
    console.log("Error Message: ", err);
});


```

``` result.json
{
    "Msg": "success",
    "Head": {
        "DocsFound": 11,
        "DocsReturn": 10,
        "SearchTime": 100
    },
    "RequestId": "A099A070-40B4-4021-9722-B8C138636FCD",
    "Auctions": [
        {
            "CategoryId": 9,
            "PicName": "12.jpg",
            "CustomContent": "k1:v12,k2:v211,k3:v311",
            "ProductId": "1011",
            "SortExprValues": "3.07306838035583;217"
        },
        {
            "CategoryId": 9,
            "PicName": "11.jpg",
            "CustomContent": "k1:v11,k2:v210,k3:v310",
            "ProductId": "1010",
            "SortExprValues": "2.97270393371582;222"
        },
        {
            "CategoryId": 9,
            "PicName": "09.jpg",
            "CustomContent": "k1:v09,k2:v208,k3:v308",
            "ProductId": "1008",
            "SortExprValues": "2.87724995613098;238"
        },
        {
            "CategoryId": 9,
            "PicName": "10.jpg",
            "CustomContent": "k1:v10,k2:v209,k3:v309",
            "ProductId": "1009",
            "SortExprValues": "2.79507827758789;235"
        },
        {
            "CategoryId": 9,
            "PicName": "02.jpg",
            "CustomContent": "k1:v02,k2:v201,k3:v301",
            "ProductId": "1001",
            "SortExprValues": "2.67687916755676;251"
        },
        {
            "CategoryId": 9,
            "PicName": "05.jpg",
            "CustomContent": "k1:v05,k2:v204,k3:v304",
            "ProductId": "1004",
            "SortExprValues": "2.67470407485962;249"
        },
        {
            "CategoryId": 9,
            "PicName": "06.jpg",
            "CustomContent": "k1:v06,k2:v205,k3:v305",
            "ProductId": "1005",
            "SortExprValues": "2.66586232185364;254"
        },
        {
            "CategoryId": 9,
            "PicName": "04.jpg",
            "CustomContent": "k1:v04,k2:v203,k3:v303",
            "ProductId": "1003",
            "SortExprValues": "2.63756942749023;255"
        },
        {
            "CategoryId": 9,
            "PicName": "01.jpg",
            "CustomContent": "k1:v01,k2:v200,k3:v300",
            "ProductId": "1000",
            "SortExprValues": "2.57631182670593;270"
        },
        {
            "CategoryId": 9,
            "PicName": "07.jpg",
            "CustomContent": "k1:v07,k2:v206,k3:v306",
            "ProductId": "1006",
            "SortExprValues": "2.52564144134521;253"
        }
    ],
    "PicInfo": {
        "CategoryId": 9,
        "AllCategories": [
            {
                "Id": 0,
                "Name": "Tops"
            },
            {
                "Id": 1,
                "Name": "Dress"
            },
            {
                "Id": 2,
                "Name": "Bottoms"
            },
            {
                "Id": 3,
                "Name": "Bag"
            },
            {
                "Id": 4,
                "Name": "Shoes"
            },
            {
                "Id": 5,
                "Name": "Accessories"
            },
            {
                "Id": 6,
                "Name": "Snack"
            },
            {
                "Id": 7,
                "Name": "Makeup"
            },
            {
                "Id": 8,
                "Name": "Bottle"
            },
            {
                "Id": 9,
                "Name": "Furniture"
            },
            {
                "Id": 20,
                "Name": "Toy"
            },
            {
                "Id": 21,
                "Name": "Underwear"
            },
            {
                "Id": 22,
                "Name": "Digital device"
            },
            {
                "Id": 88888888,
                "Name": "Other"
            }
        ],
        "Region": "140,474,36,578"
    },
    "Code": 0,
    "Success": true
}

```

前回、管理画面から投げた結果と同じ結果が出力されました。Node.jsでも簡単に検索する事ができました。