ITと哲学と

IT系エンジニアによる技術と哲学のお話。

CloudSearchのインデックスフィールド設定について

はじめに

CloudSearchはAWSが提供しているクラウドサービスの一種で、SESとかSQSなどとともにApplication Servicesに分類されるサービスです。 フルマネージドなサービスで、検索機能を提供してくれます。

CloudSearchには検索ドメインという単位があり、検索ドメインには検索可能なデータが集まるコーパスと、検索用インスタンス群が含まれます。

ユーザーは自身が持っているデータをCloudSearchにアップロードすることで、(事前に設定されたインデックスフィールドの設定に基づいて) 検索対象であるコーパスを作成することができます。

インデックスフィールドの設定はAWSコンソールやAWS CLISDKを用いて行うことができます。 AWSコンソールを用いると簡単に設定を行うことが出来ますし、公式のドキュメントでも詳しく説明されています。

ですが、自前のサービスに組み込んで運用するためには、何度でも同じ設定を復元できるようにしておく必要があると考えます。 例えば設定手順書等を作ることでAWSコンソールからの設定をサポートすることはできますが、わりと高頻度で行われるUIの変更や個々人の能力に依存するという問題が残ります。

一方、AWS CLIを用いて設定を行うことも可能であり、コードとして設定を残すことが出来ます。 そうしておくと版管理も楽にできますし、だれが実施しても同じ結果を得ることが出来ます。

そのため、インデックスフィールドの設定はAWS CLIを用いてコードで解決することが望ましいと考えます。

この記事の目的

上記の理由からインデックスフィールドの設定をAWS CLIを用いて行おうとしていたのですが、なかなかまとまった情報が見つからず、結構詰まってしまったので情報を残したいと思います。クライアントのバージョンは以下です。

 $ aws --version
 aws-cli/1.9.7 Python/2.7.9 Windows/8 botocore/1.3.7

インデックスフィールドの設定

公式ドキュメントにあるように、下記のコマンドでインデックスフィールドの設定を行うことが出来ます。

aws cloudsearch define-index-field --domain-name ドメイン名 --name インデックス名 --type インデックスタイプ

少数のインデックスフィールドのみであれば上記でも問題ありませんが、インデックスフィールドが増えてきたり、設定内容が複雑になると可読性がかなり下がってしまいます。

そこで、JSONファイルで設定を用意しておいて、それを読み込んで設定が行えるようにします。たとえばこんな感じで設定ファイルを用意します。

{
  "IndexField": {
    "IndexFieldType": "text",
    "IndexFieldName": "client_name",
    "TextOptions": {
      "HighlightEnabled": true,
      "ReturnEnabled": true,
      "SortEnabled": false,
      "AnalysisScheme": "_ja_default_"
    }
  }
}

用意したJsonファイルをUTF-8で保存し、下記のコマンドを実行するとインデックスフィールドの設定を行うことが出来ます。 ちなみにShift-JISだとCloudSearchに読み込んだ時に日本語が化けます

aws cloudsearch define-index-field --domain-name ドメイン名 --cli-input-json file://jsonファイル名

これを必要な分だけ実行することで複数のインデックスフィールドの設定をコードで行うことが出来ます。

例えばこんな感じです。 index_settingsフォルダの下に設定のjsonファイルがいくつか置かれている状態です。

for /f "usebackq" %%i in (`dir /B /S index_settings\*.json`) do (
    call aws cloudsearch define-index-field --domain-name %domain_name% --cli-input-json file://%%i
)

Jsonの中身

IndexFieldの中に IndexFieldType, IndexFieldName, TextOptions というキーが出てきます。

IndexFieldType

インデックスフィールドの型を選択します。 int型やlatlon型、text型などがあります。詳細はこちらです。

http://docs.aws.amazon.com/ja_jp/cloudsearch/latest/developerguide/configuring-index-fields.html

IndexFieldName

インデックスフィールドの名前です。

TextOptions

ここにはIndexFieldTypeで指定した型に対応したOptionsが入ります。IndexFieldTypeでtextが指定されているのでTextOptionsが入っています。

Optionsは下記の種類があります

  • IntOptions
  • DoubleOptions
  • LiteralOptions
  • TextOptions
  • DateOptions
  • LatLonOptions
  • IntArrayOptions
  • DoubleArrayOptions
  • LiteralArrayOptions
  • TextArrayOptions
  • DateArrayOptions

基本のデータ型とArrayのついた配列型があるイメージです。

Options

Optionsの中には各インデックスフィールドの詳細設定が入ります。

FacetEnabled

検索結果をフィルタするためのフィールドの定義です。 CloudSearchコンソールで検索を行って右の方に出てくるFilterSearchResultsに出てくる内容です。

ReturnEnabled

検索結果として表示するのもを設定します。 これを適切に絞り込むことで検索結果として得られるデータを小さくすることが可能です。 検索結果データの大きさは料金に関わるものなのでこれを適切に設定することはとても大切です。

SearchEnabled

検索対象とするインデックスにはこれを設定します。

SortEnabled

これが設定されているインデックスを基準として検索結果をソートできるようになります。

型と設定できる内容一覧

それぞれ設定できる内容はフィールドの型によって下記のように異なります。

int

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true,
 "SortEnabled" :true
}

double

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true,
 "SortEnabled" :true
}

literal

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true,
 "SortEnabled" :true
}

text

{
 "HighlightEnabled" :true,
 "ReturnEnabled" :true,
 "SortEnabled" :true
}

date

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true,
 "SortEnabled" :true
}

latlon

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true,
 "SortEnabled" :true
}

int-array

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true
}

double-array

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true
}

literal-array

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true
}

text-array

{
 "HighlightEnabled" :true,
 "ReturnEnabled" :true
}

date-array

{
 "FacetEnabled" :true,
 "ReturnEnabled" :true,
 "SearchEnabled" :true
}

最後にインデックスの貼り直しが必要になりますので、下記を実行してインデックスを張りなおしたら完了です。

call aws cloudsearch index-documents --domain-name %domain_name%