こちらの続きです:
Cloudant の便利な API (1) : バルクインサート


NoSQL な DBaaS である IBM Cloudant の便利で特徴的な API を紹介しています。前回は1回の POST API 呼び出しでまとめて複数のドキュメントデータを登録するバルクインサート機能を紹介しました。この登録したドキュメントデータを使って、今回からは Cloudant のユニークな API を紹介すると共に、このドキュメントデータを使った参照アプリケーションを作っていきます。

今回紹介する便利な API は View Design Document API です。Cloudant には Design Document と呼ばれる特殊なドキュメントを格納することができます。一般的なドキュメントはいわば「データとしてのドキュメント」であるのに対し、Design Document は「設計情報としてのドキュメント」です。特に今回紹介する View Design Document は複数のドキュメントの集合である「ビュー」の定義情報を保持するドキュメントです。具体的にはどのような条件を満たすドキュメントがビューに含まれるのか、その条件を満たすドキュメントのどの要素をビューに格納するのか、、といった情報を保持する、(ドキュメントデータとは異なる)特殊なドキュメントです。

なお、Cloudant の Design Document に関する API のリファレンスはこちらを参照ください:
https://docs.cloudant.com/design_documents.html


では前回作った47都道府県ドキュメントデータに View Design Document を使ってビューを作ってみます。今回はこの47ドキュメントから、いわゆる「海無し県(=栃木県、群馬県、埼玉県、山梨県、長野県、岐阜県、滋賀県、奈良県)」だけを抜き出して集めた nosea ビューを定義してみます。

まず海無し県は上述の8県です。海無し県に含まれる条件は各ドキュメントデータ(doc)の code (都道府県コード)の値が「9か、10か、11か、19か、20か、21か、25か、29のいずれかであれば海無し県」ということになります。これを JavaScript で表現すると、以下のようになります:
if( doc.code && [9,10,11,19,20,21,25,29].indexOf( doc.code ) > -1 ){
    //. doc.code が存在していて、かつその値が [9,10,11,19,20,21,25,29] のいずれかであった場合、
        :
}

この条件を満たしたドキュメントデータの各値を nosea ビューに含める、という処理の場合に指定するデータは以下のような内容になります:
{
  "language": "javascript",
  "views": {
    "nosea": {
      "map": "function( doc ){ if( doc.code && [9,10,11,19,20,21,25,29].indexOf( doc.code ) > -1 ){ emit( doc._id, {code:doc.code,prefecture:doc.prefecture,capital:doc.capital} ); } }"
    }
  }
}

JSON 内の views.nosea(ビュー名).map に、このビューへのマッピングの関数を記述します。function のパラメータである doc がデータベース内の各ドキュメントを示しており、全ドキュメントがこの関数によってマッピングされ、条件を満たしたものだけがビューに含まれるよう定義されています。

関数内で使われている emit() 関数は第一パラメータがキー、第二パラメータがデータの値となります。第二パラメータに全データを含める必要はなく、今回は code, prefecture, capital という3つのデータだけを取り出して表示するようにアプリ化するので、これらの値だけを含めるようにしました。なお、上記の定義ファイル nosea_view.json はこちらからダウンロード可能です:
https://raw.githubusercontent.com/dotnsf/samples/master/nosea_view.json


ではこの(ダウンロードした)nosea_view.json と View Design Document API を使って、実際に海無し県ビューを作ってみましょう。前回同様に、nosea_view.json を保存したディレクトリで以下のコマンドを実行します(青字は実行結果、成功した時の例です):
$ curl -u "username:password" -XPUT "https://username.cloudant.com/mydb/_design/nosea" -H "Content-Type: application/json" -d @nosea_view.json

{"ok":true, "id":"_design/nosea", "rev":"XXXX..XXXX"}

前回作成した mydb データベースの中に nosea という名前のビューを、nosea_view.json で定義された内容で作成する、という API を実行しています。username および password は Cloudant に接続するためのユーザー名およびパスワードです。詳しくは前回の記事を参照してください。

このコマンドを実行後、改めてダッシュボードの画面をリロードすると、まずドキュメントデータそのものが1つ増えて 47 データから 48 データになっていることが分かります。つまりこのコマンドでデータベース内のドキュメントが1つ追加されたことが分かります(追加されたドキュメントの id は:"_design/nosea" です):
2017100504
2017100504


また mydb データベースに nosea という Design Document が追加されていることがわかります:
2017100501


nosea を更に展開し、Views の中にある nosea を選択すると、この nosea ビューで選別されたドキュメントデータが一覧できます。想定通りの8つの海無し県が並んでいれば成功です:
2017100502


value の部分が途中で切れてみれなくなっている場合は、その部分にマウスカーソルを置いてみると value の結果がオーバーレイして表示されます。JSON ファイルで指定した通りに3つの値が取得できていることが確認できます:
2017100503


なお、ビューの一覧結果は API からも参照できます:
$ curl -u "username:password" -XGET "https://username.cloudant.com/mydb/_design/nosea/_view/nosea"

{"total_rows":8, "offset":0, "rows":[
 { "id": "aaaa..aaaa", "key": "aaaa..aaaa", "value": { "code":9, "prefecture":"栃木県", "capital": "宇都宮市" } },
 { "id": "bbbb..bbbb", "key": "bbbb..bbbb", "value": { "code":10, "prefecture":"群馬県", "capital": "前橋市" } },
    :
 { "id": "cccc..cccc", "key": "cccc..cccc", "value": { "code":29, "prefecture":"奈良県", "capital": "奈良市" } }
]}


今回は Cloudant の View Design Document を使うことで特定条件を満たすドキュメントデータだけを選別してビューにする例を紹介しました。このようなドキュメント集合体の定義が1つのドキュメントデータとしてデータベース内に格納される、という所が Cloudant のユニークな点であると同時に、その集合体が「ビュー」と呼ばれている点などがなんとなくノーツっぽい※ところもあって、個人的には親和性を感じます。

※ちなみに Cloudant のベースとなっている CouchDB を開発した Damien Katz さんは元 Lotus のエンジニアです。
https://www.linkedin.com/in/damienkatz/


なお、次回は今回紹介した View Design Document を使って定義したビューを「どのような UI で見せるか」という情報を定義するための List Design Document を紹介する予定です。