アプリに高い検索機能を簡単に速攻で組み込む by Amazon CloudSearch

CloudSearchを使用することで、例えば、茅ヶ崎を茅ケ崎として認識させたいなどの高い検索機能を実現できます。

類似機能ではAmazon Elasticsearch Serviceがありますが、両者の違いは簡単に言うと、

Cloudsearch: 運用が楽
Elasticsearch Service: 設計が必要だが、カスタマイズ性が高い

こんなイメージで良いかと思います。

#コンソール上の操作
##事前準備
CloudSearchを操作するにあたって事前に検索の対象となるcsvファイルを作成しておく。例えば、以下のように作成する。

```stations.csv
"id", "line_id", "station"
000001,1234,"東京"
000002,1234,"新橋"
000003,1234,"品川"
000004,1234,"川崎"
000005,1234,"横浜"
000006,1234,"戸塚"
000007,1234,"大船"
000008,1234,"藤沢"
000009,1234,"辻堂"
000010,1234,"茅ケ崎"
```

マネジメントコンソールから、CloudSearchを選択

##Domainの作成
最初にDomainを作成する。

Create a new search domainを選択
現れたダイアログボックスに以下のように内容を入力していく


###NAME YOUR DOMAIN
以下のように入力してCONTINUEを選択
Search Domain Name: cloudsearch-test

Desired Instance Type: search.m1.small
Desired Replication Count: 1

「インスタンスタイプやレプリケーション数を変更すると無料枠を超えて追加料金が発生する」かもといった注告が出るがOKを選択

###CONFIGURE INDEX
How do you wanto to configure your index fields?と聞かれるので、以下のものを選択
Analyze sample(s) from my local machine

現れる画面からファイルを選択で先ほど作成したcsvファイルを選択してCONTINUEを選択

###REVIEW INDEX CONFIGURATION
取り込んだcsvファイルを元に自動でフィールドを生成してくれる。内容を確認したら、Continueを選択

###SETUP ACCESS POLICIES
IAMポリシーの設定をする。代表的なものが予め4つ用意されているので参考にすると良い。ここでは、テストなので以下のものを選択

```Allow open access to all services (not recommended because anyone can upload documents)```

すると以下のようなものが生成される

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "*"
        ]
      },
      "Action": [
        "cloudsearch:*"
      ]
    }
  ]
}
```

内容を確認したら、Continueを選択

###CONFIRM
これまでの設定内容が表示される。内容を確認したらConfirmを選択

Domainの作成が開始される。LOADING→PROCESSING→ACTIVEの状態に変化する。10分ちょっとで変わるのでそれまで待機。

##検索対象ファイルのアップロード
Upload Documentsを選択
現れるダイアログボックスに以下のように入力していく

###DOCUMENTSOURCE
What do you want to upload?に対して、
File(s) on my local diskを選択
ファイルを選択から先ほどアップロードしたstations.csvを選択
Continueを選択

###REVIEW DOCUMENTS
内容を確認してUpload Documentsを選択

###DOCUMENT SUMMARY
内容を確認してFinishを選択


以上で、CloudSearchの設定は完了。
ナビゲーションペインの[Run a Test Search]から実際に検索のテストが可能である。

例えば、冒頭で説明した茅ヶ崎を茅ケ崎などのような検索をしたい場合はOptionsから以下のような設定にする。

Query Parser: Simple(デフォルト値)
Default Operator: or(デフォルト: and)
Sort by: _score Descending(デフォルト値)

#アプリ内から使用する
ここでは、PHPのWebアプリケーションからCloudSearchの操作する場合を取り上げる。

##Composerによるインストール
Composerのインストール

```bash
curl -sS http://getcomposer.org/installer | sudo php
```

composer.jsonを作成して、以下のように記述。ここではAWS SDK for PHPのv2(ドキュメント: http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-cloudsearch.html )を使用する。v3(ドキュメント: http://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudSearch.CloudSearchClient.html )もあるので、v3を使用する場合は下記のPHPのサンプルコードも適宜変更を加える。

```composer.json
{
    "require": {
        "aws/aws-sdk-php": "2.*"
    }
}
```

Composerにより、AWS SDK for PHPをダウンロード

```bash
php composer.phar install
```

例えば、以下のように実装する。autoload.phpを読み込むパスやAccess keyやsecret keyは適宜変更する。

```php
<?php

require_once('<Path>/<To>/vendor/autoload.php');

$DOMAIN_NAME = '＜CloudSearchのドメイン名＞';

$client = CloudSearchClient::factory([
	'key' => 'AKIA***************',
	'secret' => '****************************',
	'profile' => 'default',
	'region' => Region::AP_NORTHEAST_1
]);

$domainClient = $client->getDomainClient($DOMAIN_NAME, [
	'credentials' => $client->getCredentials()
]);
$result = $domainClient->search([
	'query' => $_POST['input_station'],
	'queryParser' => 'simple',
	'queryOptions' => "{defaultOperator: 'or'}",
	'highlight' => "{station: {format:'text'}}",
	'return' => 'station',
	'size' => 1
]);

$stations = [];
foreach ($result['hits']['hit'] as $hit) {
        $stations[] = $hit['fields']['station'][0];
}

var_dump($stations);

```



[](
Amazon EC2外からだと、AWS access keyとsecret access keyを指定する¥
¥
```
Aws\Common\Exception\InstanceProfileCredentialsException [ Error ]:
Error retrieving credentials from the instance profile metadata server. When you are not running inside of Amazon EC2, you must provide your AWS access key ID and secret access key in the "key" and "secret" options when creating a client or provide an instantiated Aws\Common\Credentials\CredentialsInterface object. ([curl] 28: Connection timed out after 5007 milliseconds [url] http://169.254.169.254/latest/meta-data/iam/security-credentials/
```
)

#(Appendix)AWS CLI コマンド一覧

```
build-suggesters
create-domain
define-analysis-scheme
define-expression
define-index-field
define-suggester
delete-analysis-scheme
delete-domain
delete-expression
delete-index-field
delete-suggester
describe-analysis-schemes
describe-availability-options
describe-domains
describe-expressions
describe-index-fields
describe-scaling-parameters
describe-service-access-policies
describe-suggesters
index-documents
list-domain-names
update-availability-options
update-scaling-parameters
update-service-access-policies
```

#参考
コンソールからの操作
http://qiita.com/okuda_h/items/0dcb27abeac7641ba2a4

PHP SDK for PHP
http://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.CloudSearchDomain.CloudSearchDomainClient.html
http://techlog.voyagegroup.com/entry/2015/04/15/151553