2014年12月3日水曜日

Parse.comの$inQueryというクエリについて調べてみた

概要

前回前々回と別のクエリの説明をしてきて今回は3つ目のクエリで$inQueryというクエリを説明したいと思います
$inQueryPointerで紐付いているデータ取得するためのクエリです

環境

  • Mac OS X 10.8.5
  • Parse.com(2014/12/03 時点)
  • curl

説明

$inQueryPointerという型のカラムに対して実行できます
実際にPointer型のカラムおよびデータを作成してからクエリを発行したいと思います
今回はusersクラスとuserAttributeクラスをPointerで紐付けたいと思います

UIで事前にデータを投入

データはUIから投入可能です

userAttributeクラスを作成

userAttributeクラスは自分で作成するクラスです
ダッシュボードから「+ Add Class」を選択します
するとダイアログが表示されるのでクラス名に「userAttribute」と入力して「Create Class」をクリックします

userAttributeクラスが作成できたらカラムを追加します
「+Col」をクリックするとカラムを追加するダイアログが表示されます
「Select a type」でStringを選択します
カラム名は「skill」と入力し「Create Column」でカラムを作成します
create_class.png
まだデータがない状態で上記のようになればOKです
追加したskillカラムが見つからないという場合は画面をリロードするか画面の右端にカラムが作成されていることがあるのでドラッグ&ドロップでカラムを左に持ってくればOKです

ついでにデータも登録します
「AddRow」をクリックしskillに「Java」と入力してデータを登録します
regist_data.png
これでuserAttribute(参照先)側のデータ登録は完了です
次にusers(参照元)のデータを作成していきます

usersクラスにユーザを追加する

usersにユーザを登録します
「AddRow」からユーザを登録します、usernameとpasswordを入力してユーザを登録します

またPointer型のデータを管理するカラムを追加します
「+Col」をクリックすると追加するダイアログが表示されます
「Select a type」でPointerを選択します
すると参照先のクラスを選択するための「Target class」というプルダウンが表示されるので先ほど作成したuserAttributeクラスを選択します
そしてカラム名を入力します、今回は「refSkill」という名前で作成します
add_column.png
入力した「Create Column」をクリックします

とりあえず以下のような状態になればOKです
regist_user.png

userAttributeへの参照情報をusersに登録する

先ほど作成したユーザにuserAttributeへの参照情報を追加します
UIから参照情報を登録するのは非常に簡単です
まず、userAttributeに登録したデータのobjectIdをメモしておきます
今回であればJavaというskillの「Iy5hovxqVs」がそれにあたります
この情報をusersクラスのrefSkillカラムに登録します

usersクラスを表示します
refSkillカラムのダブルクリックし編集可能状態にして先ほどのobjectIdを貼り付ければ完了です
regist_pointer_info.png
上記のようにobjectIdが表示されたボタンが作成されればOKです

上記のようにボタンにならない場合はrefSkillカラムを追加するときの型がPointerになっているか再度確認してください
String型になっている場合はボタンにはならず、ただobjectIdが表示されるだけとなります

この状態でボタンをクリックするとuserAttributeクラスの参照先のデータに飛ぶことがわかると思います

ようやく$inQueryを発行できる準備が整いました

curlでクエリを作成する

今回実行するクエリは以下の通り
このクエリの流れを説明していきます

curl -X GET \
  -H "X-Parse-Application-Id: 1234567890abcdefghijklmnopqrstuvwxyz" \
  -H "X-Parse-REST-API-Key: 1234567890abcdefghijklmnopqrstuvwxyz" \
  -G \
  --data-urlencode 'where={"refSkill":{"$inQuery":{"where":{"skill":{"$exists":true}},"className":"userAttribute"}}}' \                
  https://api.parse.com/1/users

動作の仕組み

クエリの流れは

  1. userAttributeクラスのskillカラムにデータを持つオブジェクトを検索する
    {"where":{"skill":{"$exists":true}},"className":"userAttribute"}の部分
  2. 上記の検索結果で絞りこまれたデータからobjectIdの一覧を取得する
  3. 取得したobjectIdの一覧とusersクラスのrefSkillカラムのデータを比較する
    where={"refSkill":{"$inQuery":の部分とURIで指定しているクラスの部分
  4. 一致するデータをusersクラスから取得して返却する

という流れになります
実際にクエリを投げた際のレスポンスは以下の通りです

{
    "results": [
        {
            "createdAt": "2014-12-03T05:50:27.239Z",
            "objectId": "YzXJMy6tgH",
            "refSkill": {
                "__type": "Pointer",
                "className": "userAttribute",
                "objectId": "Iy5hovxqVs"
            },
            "updatedAt": "2014-12-03T06:04:27.942Z",
            "username": "testUser"
        }
    ]
}

users側の情報が取得できていることがわかると思います
今回は1人のユーザしかいませんでしたが、refSkillを参照するユーザが複数いればレスポンスにも複数のユーザが含まれます

userAttribute側に複数のskillデータを登録して別のskillを参照するユーザを登録してあげても結果は複数のユーザが返却されます

また今回userAttribute側を検索する際のクエリ({"where":{"skill":{"$exists":true}},"className":"userAttribute"}の部分)は$exists:trueというクエリを使っています
これは指定したカラムにデータが存在するデータを取得するという条件になります
ここは自由に変更可能で例えばJavaというskillを持つユーザだけを取得したいのであれば
{"where":{"skill":"Java"}という風に書き換えればJavaに紐づくユーザだけを取得することができます

このように$inQueryを使うことで条件に合致する参照先のデータを1つクエリで取得することができるようになります
もちろん参照先のデータはPointer型で持つ必要はあります

参考サイト

0 件のコメント:

コメントを投稿