以前に Cloudant データベースにインデックスを作成する方法を紹介しました:
Cloudant 内のデータをインデックスして検索する


上記エントリの (2) で紹介した方法は単独のフィールド(cputemp)にインデックスを作成して、数値が一定値よりも大きいレコードを探す、というクエリーができるようにしたものでした。

では例えば、複数フィールドで検索条件を指定するようなクエリーを実行したい場合はどのようにすればいいでしょうか? 例えば以下のようなレコードが Cloudant のデータベース db に入っているものとします:
IDNAMEAGE
1鈴木20
2鈴木41
3佐藤20
4田中35
5田中15
: : :

(↑ RDB っぽく書いてますが、実際には JSON フォーマットで {"ID":1, "NAME":"鈴木", "AGE":20} のように格納されているとします)


この時に「30歳以上の鈴木さん」とか「20歳の田中さん(実際には見つからない)」という条件でレコードを検索したい場合、どのようなインデックスを作って、どのように検索すればいいでしょうか?


まず、NAME と AGE の2つのフィールドにまたがるインデックスを用意する必要があります。Cloudant の管理画面から目的のデータベースを選び、"Design Documents" の右にある + をクリックして、"Query Indexes" を選択してください:
2016101001


Index の定義画面が表示されたら、テキストフィールド内に以下の値を記述します:
{
  "index": {
    "fields": [
      {
        "name": "NAME",
        "type": "string"
      },
      {
        "name": "AGE",
        "type": "number"
      }
    ]
  },
  "type": "text",
  "name": "db-index"
}

string 型の NAME と、number 型の AGE を指定して db-index という名前のインデックスを作ります。入力後に "Create Index" ボタンをクリックすると実際にインデックスが作成されます:

2016101002


インデックス作成後、実際にクエリーを実行してみましょう。例えば「30歳以上の鈴木さん」を検索するには以下のような POST リクエストを発行します(curl で実行する場合の例):
$ curl -X POST https://username:password@XXX-bluemix.cloudant.com/db/_find -d '{"selector":{"NAME":{"$eq":"鈴木"},"AGE":{"$ge":30}}}'
(Cloudant のサーバーが XXX-bluemix.cloudant.com 、ユーザー名が username 、パスワードが password であるものと仮定しています)

同様にして「20歳の田中さん」を検索する場合はこのようなリクエストを発行することになります:
$ curl -X POST https://username:password@XXX-bluemix.cloudant.com/db/_find -d '{"selector":{"NAME":{"$eq":"田中"},"AGE":{"$eq":20}}}'

それぞれ _find にセレクター(selector) を指定して POST リクエストを発行しています。そしてそのセレクターの中で存在するインデックスを使った検索条件を指定して、クエリーを実行しています。その際にあらかじめ作成しておいたインデックス(db-index)が使われて、想定したレコードを検索することができるようになる、というものです。

この「想定するクエリーを実行するためのインデックスをあらかじめ用意しておく」というのが RDB に比べてちと面倒で、クエリーの柔軟性にかける部分ではありますが、Cloudant はこういった方法でクエリーに対応しています。