LoginSignup
23
24

More than 5 years have passed since last update.

ParseQuery の取扱説明書

Posted at

Parse.com を使ってバックエンドを構築した時、Android からは、ParseSDK を用いてそれらにアクセスするのが最も簡単かつ手軽にできます。
そして、Parse に保存されたデータにアクセスする際頻繁に使うであろうクラスが、ParseQueryです。

ParseQuery の概要

ParseQuery は、指定した条件を満たすレコードの一覧を得るために使います。
例えば、あるカラムの数字が x 以上だとか、あるカラムの文字列が y と一致するとか、レコードのオフセットやリミットも指定できます。

リレーショナルなレコード

Parse のデータベースは、リレーショナルなデータを持たせることが出来、いくつかの種類があります。

Pointer

カラムのデータが、別のクラスが持つ特定のレコードを指し示す場合に用いられます。リレーショナルデータベースで言うところの外部キーのように働きます。

Relation

名前の通り、関係を持っているデータの集合を取り扱うための型です。リレーショナルデータベースであれば、関係テーブルを用いて表現する内容を、カラムの型として取り扱えるようにしてくれています。

ParseQuery の使い方

PointerRelation以外は、特に指定のない限りデフォルトでどの型のカラムであっても結果として取得することが出来ますが、PointerRelationは特別扱いされ、リクエストの際に指定しない限りレスポンスには存在しない事になったり、そもそも取得の方法が別に用意されていたります。

Pointer を含める

ParseQuery#include(String)で、引数に指定したカラムのPointerの内容を一緒に返してくれます。
Pointerで指定したデータの中に、別のクラスのPointerを型とするカラムがある場合、別途それも含まれるよう指示しないと結果が得られません。


ParseQuery<Hoge> query = new ParseQuery<Hoge>(); // Hoge クラスのテーブルにクエリを投げる
query.include("huga"); // Huga クラスのデータを持つ huga カラムに対し、インクルード指定することで、huga カラムに指定された Huga クラスのレコードが返ってくるようになる
query.include("huga.piyo"); // Huga クラスの piyo カラムは Piyo クラスへの Pointer である為、ドットでつないでインクルードする
query.include("huga.piyo.foo");
query.include("huga.piyo.foo.bar");
query.include("huga.piyo.foo.bar.baz"); // ドットは 3 個までの制約があるため、インクルード出来ない

言うまでもなく、インクルードが増えれば増えるほどレスポンスが返ってくるまでの時間は長くなります。

Relation を含める

Pointerのようには含められません。

ではどうするかというと、ParseQueryの結果からParseRelationを取得し、このParseRelationが持つクエリを使って再度リクエストを投げることになります。


ParseQuery<Hoge> query = new ParseQuery<Hoge>();
List<ParseObject> result = query.find();

for (ParseObject object: result) {
    ParseRelation relation = object.getRelation("data");
    ParseQuery relationQuery = relation.getQuery();
    List<ParseObject> relationResult = relationQuery.find();
    ...
}

言うまでもなく、取得したいRelationの数だけクエリを発行してfor文を回すので、最初にリクエストを生成してから、最終的な結果を得るまでには相当の時間を費やすことになります。

Relation のパフォーマンスチューニングをしたい

例えば、関係を多数持つカラムを考えた時、その上限が明らかになっている場合、Pointerの配列型としてカラムを定義する手段がありえます。
Parse のデータベースのカラムには、配列型が存在し、内部的には数字や文字列以外も配列として保持することが出来、Pointerも配列にすることが可能です(とは言え、Relationの配列を作れるかどうかは未検証ですが…)。

こうすることで、ParseQuery#include(String)を用いて、一回のリクエストですべての関係を引いてくることが出来るようになります。
もうfor文をネストしてその中で何度もリクエストを飛ばすようなこともなくなります。

まとめ的な

ParseSDK はとかく内部で色々やっているらしく、ミューテックスを使って何らかロックを取得しているようですし、**InBackground()でも平気で MainThread をブロックしに来てくれますし、わりと効率の悪い感じがあるので、できれば REST ですべてをさばけるようになるとシアワセかもしれません。

23
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
24