自社サイトにBing Custom Searchを設置（サイト内検索）

#Bing Custom Searchの設置方法

公式マニュアルが分かりにくいので備忘録。

[microsoft公式マニュアル: Bing Custom Searchクイック スタート](https://docs.microsoft.com/ja-jp/azure/cognitive-services/bing-custom-search/quick-start)

Google Custom Searchは広告がひっついてくるのでBingにリプレイスしようと。Google Custom Searchと同じように＜script＞タグを埋め込めばいいのだろうとマニュアルを見たが分かりにくい。
【結論】＜script＞タグを埋め込めばよい。

以下手順。

### AzureでCognitive Servicesのサブスクリプションキーを取得
まずはサブスクリプションキーをば。

- Azure PortalのCognitive Services画面にいく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/cee3138f-788e-d9e8-d53f-884de28982a9.png)

- 追加ボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/fba56cd6-cea7-d19d-c6f5-af365175a13c.png)

- Bing Custom Searchを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/c2256f2b-2fff-1bf0-fff7-9b48c563aab6.png)


- 作成ボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/dbe0d5b7-6f2c-e430-d4ff-8a02bfee9aac.png)

- 名前、サブスクリプションの分類、価格レベル（無料枠であればF0を選択）、リソースグループを入力して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/79c7f89b-aa3d-6cec-f192-ce8e66647e20.png)

- 作成できたらキーとエンドポイントができてる。このキーがサブスクリプションキー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/0e4b1ec7-6011-51d8-cd44-2c239036f5b1.png)

###Bing Custom Search インスタンスの作成
これは公式マニュアル通りの手順で良い。

- Bing Custom Search ポータル へ（https://www.customsearch.ai/applications）
- New Instance
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/87cd5cf7-1dcf-2981-b739-9512ca0435fc.png)

- instance名を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/edbb402d-4cb1-e851-b319-3916a88203e1.png)

- 自サイトのドメイン名を入力して＋をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/beefb413-50b7-dd8e-5728-dd91a618fcec.png)

- インスタンスができたらHosted UIをクリックして表示オプション的な設定をしていくことになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/c1e3b871-2744-2dcf-5375-a7656fbfe735.png)

- ①～③は見た目の設定なので適当に。ただ④でSearch Keyを設定しないと機能しない。ここにサブスクリプションキーを入力する(Search KeyじゃなくてSubscription Keyと書いてほしい汗）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/1c5ebc84-a861-54f4-3c96-3635085ce2aa.png)

- そうしたら画面右上のPublishボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/f2cbd097-8891-2a3a-796b-ba9510998a46.png)

- Productionページに行きますか？それともこのページにとどまりますか？と聞かれるのでProductionページ行くをクリック。次のような画面に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/b0a1504d-8422-e8ae-c027-40c8ce6d9b4e.png)


- このページでいちおうクエリを試す（やらなくてもいいけど）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/b6b86658-c0fa-c3fa-70d9-cec16946635b.png)
CallをクリックでJSONが返ってくるはず。

- Hosted UIをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/867b34bd-3d27-86f8-5cc3-ba5ef8d820f1.png)

- この画面にある＜Script＞コードを自サイトに埋め込めばよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/1f64d9d5-f25f-9399-2a30-4cb7128a89b6.png)


###Bing Custom Search エンドポイントを呼び出す
次の手順、とマニュアルには[Node.js を使用して Bing Custom Search エンドポイントを呼び出す](https://docs.microsoft.com/ja-jp/azure/cognitive-services/bing-custom-search/call-endpoint-nodejs) に行くボタンがあるが、これも必要な手順かと迷うが、いらない。表示画面をカスタマイズしたいとかなければ必要ない。

###スクリプトコードを埋め込む

当方Angular8なのでスクリプトコードは埋め込めない。
以下のやり方でやった。

.ts

```typescript

  ngOnInit() {
  
    const script = document.createElement('script');
    script.async = true;
    script.type="text/javascript";
    script.src = 'https://ui.customsearch.ai/api/ux/rendering-js?customConfig=fcbxxxx3-xxxx-xxxxx-xxxxx-eexxxxa516c2&market=ja-JP&version=latest&q=';
    script.id = 'bcs_js_snippet';

    const div = document.getElementById('script');
    div.insertAdjacentElement('afterend', script);
  }
```

HTML

```html
<div id="script"></div> 
```

とりあえず以上。
<br>
###検索結果を表示したあと、表示をリセットする
Google Custom Searchのように表示結果を別ページに呼び出すオプションがないのでSPAだと他の画面に飛んでも表示されっぱなしになってしまう。簡易的な解決方法はページリロード。
ボタンをつけて、クリックするとリロードするようにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/f0393334-15f2-8ff2-6f3d-6cef23ef2ca0.png)

HTML

```html
  <table style="border: white; border:0; width: 100%;">
    <tr>
      <td style="width: 95%">
        <div id="script"></div>  
      </td>
      <td style="width: 5%; vertical-align: top;">
        <button style="margin-left: 0.5em;" class="simple_square_btn2" (click)="reset()">
            表示<br>リセット
        </button>
      </td>
    </tr>
  </table>
```
CSS

```css
.simple_square_btn2 {
	display: block;
	position: relative;
    width: 50px;
    height: 46px;
    padding: 0.3em;
	text-align: center;
	font-size: x-small;
	text-decoration: none;
	color: #1B1B1B;
	background: #fff;
	border:1px solid #1B1B1B;
}
```

TS

```typescript
    // サーチクリア関数(リロードするだけ）
    reset() {
      location.reload();
    }
```

<br>
####Appendix：Angularでエンドポイントを呼び出すコード

カスタマイズしたい場合のコードはAngularの場合、いかのような感じだろうか？テストしてないので動かないと思う。あくまでイメージ。

TS

```typescript
import { Component, OnInit } from '@angular/core';
import { Observable } from  "rxjs";
import { HttpClient,HttpHeaders,HttpParams } from '@angular/common/http';

class bing {
  name: string;
  url: string;
  displayUrl; string;
  snippet: string;
  dateLastCrawled: string;
}

@Component({
  selector: 'app-bing',
  templateUrl: './bing.component.html',
  styleUrls: ['./bing.component.css']
})

export class BingComponent implements OnInit {

  bingObservable: Observable<bing[]>;

  subscriptionKey = 'a053xxxxxxxxxxxxxxxxxxxxf4ac'; //'YOUR-SUBSCRIPTION-KEY'
  customConfigId = 'fcbxxxx3-xxxx-xxxx-9676-ee7xxxxx516c2'; //'YOUR-CUSTOM-CONFIG-ID'; 
  searchTerm = '';

  url = 'https://bij.cognitiveservices.azure.com/bingcustomsearch/v7.0/search?' + 
  'q=' + this.searchTerm + '&' + 'customconfig=' + this.customConfigId + '&' + 'mkt=ja-JP';

  options = {
    headers: new HttpHeaders().append("Ocp-Apim-Subscription-Key", this.subscriptionKey),
    params: new HttpParams().append("url", this.url)
  }

  loadBing() {
    this.bingObservable = this.http.get<bing[]>(this.url, this.options);
    console.log('◆' + this.bingObservable)
  }

  constructor() {
  }

  ngOnInit() {
  }

```

HTML

```html
<ul *ngIf="bingObservable| async as results else empty">
  <li *ngFor="let result of results">
  </li>
</ul>
```

<br>
参照：
[Angular 9/8 Http - How to Use HttpClient Module with Examples](https://www.techiediaries.com/angular-http-client/)
[Angularのテンプレート内で script タグを読み込む方法](https://qiita.com/kenya-112163/items/c21cb98f8c8a96bf085d)
[how to use bing search in my angular app.?
](https://stackoverflow.com/questions/49006045/how-to-use-bing-search-in-my-angular-app)