検索のサンプルコード
さまざまな検索の例を以下に示します。
Bucket 内の全 Object の取得
まずは、もっとも単純な検索として Bucket 内の全ての Object を取得する例について説明します。
-
// Create a query that returns all KiiObjects. KiiQuery all_query = new KiiQuery(); try { // Query KiiObjects. KiiQueryResult<KiiObject> result = Kii.bucket("AppBucket") .query(all_query); // Alternatively, you can use: // KiiQueryResult<KiiObject> result = Kii.bucket("AppBucket") // .query(null); List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with KiiObjects in the result. } } catch (IOException e) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
// Create a query that returns all KiiObjects. KiiQuery all_query = new KiiQuery(); // Query KiiObjects. Kii.bucket("AppBucket") .query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with KiiObjects in the result. } } }, all_query); // Alternatively, you can use: // Kii.bucket("AppBucket") // .query(..., null);
ここでは以下の処理が行われています。
KiiClause
を何も指定せずにKiiQuery
インスタンスを作成し、"all" 検索用のクエリインスタンスを作成。- このクエリインスタンスを、検索対象 Bucket の
query
メソッドに渡して実行。別の方法として、query()
メソッドを null 指定で実行することもできます。 KiiQueryResult
として返却された検索結果をgetResult()
メソッドを用いてパース。
Bucket に対して "all" 検索を実施しているため、検索結果には Bucket 内の全ての Object が含まれます。
なお、期待どおりに取得できない場合、スコープの違い もご確認ください。
複数条件の検索
次に、以下の条件で検索を実行する例を取り上げます。
- "gender" フィールドの値が "Female"、かつ "age" フィールドの値が 18 より大きい
- "age" フィールドの昇順で検索結果をソート。
- 一度の検索実行で取得する検索結果の最大件数を 10 件に設定。
-
// Prepare the target bucket to be queried. KiiBucket bucket = Kii.bucket("AppBucket"); // Create a query with clauses. KiiQuery query = new KiiQuery(KiiClause.and( KiiClause.equals("gender", "Female"), KiiClause.greaterThan("age", 18))); // Define how to output the query result. query.sortByAsc("age"); query.setLimit(10); try { // Query KiiObjects. KiiQueryResult<KiiObject> result = bucket.query(query); List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with the first 10 KiiObjects. } // If there is more data to retrieve while (result.hasNext()) { // Query the next 10 KiiObjects with pagination. result = result.getNextQueryResult(); objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with the next 10 KiiObjects. } } } catch (IOException e) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
// Prepare the target bucket to be queried. KiiBucket bucket = Kii.bucket("AppBucket"); // Create a query with clauses. KiiQuery query = new KiiQuery(KiiClause.and( KiiClause.equals("gender", "Female"), KiiClause.greaterThan("age", 18))); // Define how to output the query result. query.sortByAsc("age"); query.setLimit(10); // Query KiiObjects. bucket.query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with the first 10 KiiObjects. } // If there is more data to retrieve if (!result.hasNext()) { return; } // Query the next 10 KiiObjects with pagination. result.getNextQueryResult(this); } }, query);
ここでは以下の処理が行われています。
equals()
メソッドとgreaterThan()
メソッドを用いて個々の検索条件を定義。さらにこれらの検索条件をand()
メソッドで結合したKiiClause
インスタンスを用いてKiiQuery
インスタンスを作成。KiiQuery
インスタンスのsortByAsc()
メソッドを実行して、ソート順序を指定。KiiQuery
インスタンスのsetLimit()
メソッドを実行して、一度に取得する検索結果の最大件数を指定。KiiQuery
インスタンスを指定して検索対象 Bucket のquery()
メソッドを実行し、検索を実施。KiiQueryResult
インスタンスとして返却された検索結果をgetResult()
メソッドを用いてパース。
今回の例では、ページネーションを考慮した検索結果のパースを行っています。
- 検索結果のパース終了後、
KiiQueryResult
インスタンスのhasNext()
メソッドを実行して、未取得の検索結果が存在するか確認。 - もし未取得の検索結果が存在する場合は、
getNextQueryResult()
メソッドを実行して、次の検索結果 10 件を含むKiiQueryResult
インスタンスを取得。
位置情報による検索
次に、位置情報に基づく Object 検索を行う例を挙げます。
まず、以下のように "location" というフィールドに GeoPoint を持つ Object が存在するものとします。
-
KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); // Create a KiiObject. KiiObject object = bucket.object(); GeoPoint point = new GeoPoint(35.661561, 139.769595); object.set("location", point); try { // Save the KiiObject. object.save(); } catch (IOException ioe) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); // Create a KiiObject. KiiObject object = bucket.object(); GeoPoint point = new GeoPoint(35.677379, 139.702148); object.set("location", point); // Save the KiiObject. object.save(new KiiObjectCallBack() { @Override public void onSaveCompleted(int token, KiiObject object, Exception exception) { if (exception != null) { // Handle the error. return; } } });
GeoBox(長方形エリア)による Object 検索を行うには、以下の様な処理を行います。
-
// Prepare the target bucket to be queried. KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); try { // Define a GeoBox clause with northeast and southwest points. GeoPoint sw = new GeoPoint(35.52105, 139.699402); GeoPoint ne = new GeoPoint(36.069082, 140.07843); KiiClause clause = KiiClause.geoBox("location", ne, sw); // Create a query with the GeoBox clause. KiiQuery query = new KiiQuery(clause); // Query KiiObjects. KiiQueryResult<KiiObject> result = bucket.query(query); // Do something with the result. } catch (IOException ioe) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
// Prepare the target bucket to be queried. KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); // Define a GeoBox clause with northeast and southwest points. GeoPoint sw = new GeoPoint(35.52105, 139.699402); GeoPoint ne = new GeoPoint(36.069082, 140.07843); KiiClause clause = KiiClause.geoBox("location", ne, sw); // Create a query with the GeoBox clause. KiiQuery query = new KiiQuery(clause); // Query KiiObjects. bucket.query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } // Do something with the result. } }, query);
この例のように、GeoBox の検索条件は北東点と南西点を表す GeoPoint を指定して geoBox()
メソッドを実行することにより定義します。
次に、GeoDistance(円エリア)による Object 検索を行う処理例を以下に示します。この例では 2 つの GeoDistance を定義しており、これら 2 つの GeoDistance が交わるエリアにマッチする Object を検索しています。また、検索結果を片方の GeoDistance の中心点より近い順にソートしています。
-
// Prepare the target bucket to be queried. KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); try { // Define the first GeoDistance clause. String distanceField1 = "distance_from_center1"; GeoPoint center1 = new GeoPoint(35.658603, 139.745433); KiiClause clause1 = KiiClause.geoDistance("location", center1, 3000, distanceField1); // Define the second GeoDistance clause. GeoPoint center2 = new GeoPoint(35.681382, 139.766084); KiiClause clause2 = KiiClause.geoDistance("location", center2, 3000, null); // Create a query with the GeoDistance clauses and set the sort order. KiiQuery query = new KiiQuery(KiiClause.and(clause1, clause2)); String sortKey = "_calculated." + distanceField1; query.sortByAsc(sortKey); // Query KiiObjects. KiiQueryResult<KiiObject> result = bucket.query(query); // Do something with the result. // This example just fetches the first KiiObject. List<KiiObject> objects = result.getResult(); KiiObject objInquired = objects.get(0); // Get the distance from the center to the location. double distance = objInquired.getJSONObject("_calculated") .getDouble(distanceField1); } catch (IOException ioe) { // Handle the error. } catch (AppException e) { // Handle the error. } catch (JSONException jse) { // Handle the error. }
-
// Prepare the target bucket to be queried. KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); // Define the first GeoDistance clause. final String distanceField1 = "distance_from_center1"; GeoPoint center1 = new GeoPoint(35.658603, 139.745433); KiiClause clause1 = KiiClause.geoDistance("location", center1, 3000, distanceField1); // Define the second GeoDistance clause. GeoPoint center2 = new GeoPoint(35.681382, 139.766084); KiiClause clause2 = KiiClause.geoDistance("location", center2, 3000, null); // Create a query with the GeoDistance clauses and set the sort order. KiiQuery query = new KiiQuery(KiiClause.and(clause1, clause2)); String sortKey = "_calculated." + distanceField1; query.sortByAsc(sortKey); // Query KiiObjects. bucket.query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } // Do something with the result. // This example just fetches the first KiiObject. List<KiiObject> objects = result.getResult(); KiiObject objInquired = objects.get(0); try { // Get the distance from the center to the location. double distance = objInquired.getJSONObject("_calculated") .getDouble(distanceField1); } catch (JSONException jse) { // Handle the error. } } }, query);
ここでは以下の処理が行われています。
- 中心点を表す GeoPoint、半径(メートル)、中心点からの距離格納用フィールド(オプショナル)を指定して
geoDistance()
メソッドを実行し、GeoDistance の検索条件を定義。 - 2 つの GeoDistance を
and()
メソッドで結合したKiiClause
インスタンスを用いてKiiQuery
インスタンスを作成。 KiiQuery
インスタンスのsortByAsc()
メソッドを実行して、ソート順序を指定。KiiQuery
インスタンスを指定して検索対象 Bucket のquery()
メソッドを実行し、検索を実施。KiiQueryResult
インスタンスとして返却された検索結果をgetResult()
メソッドを用いてパース。
GeoDistance による検索を行った場合、検索にマッチした Object のそれぞれに対して、中心点からの距離(メートル)を Kii Cloud にセットさせることができます。今回の例では、GeoDistance1 の中心点からの距離を Kii Cloud にセットさせています。
- 距離は、
geoDistance()
メソッド実行時に指定した距離格納用フィールドにセットされます。 - この距離を用いてソートを行う場合は、例のように "_calculated." の後に距離格納用フィールド名をアペンドした文字列を
sortByAsc()
メソッドに指定します。 - 検索結果より距離を取得するには、例のように Object の "_calculated" フィールドを
getJSONObject()
メソッドで取得し、さらにgetDouble()
メソッドを実行して距離格納用フィールドより距離を取得します。
所定キーによる検索
次に、所定キーを検索条件に使った検索の例を挙げます。
次のコードでは、ログイン中のユーザーによって作成された Object のうち、更新されていないものと 1 日以内に作成されたものの両方を取得する条件で検索しています。ユーザー ID や作成日時はここに示すような方法で比較できます。
-
// Prepare the target bucket to be queried. KiiBucket bucket = Kii.bucket("AppBucket"); // Get values to use in query conditions. String userId = KiiUser.getCurrentUser().toUri().getLastPathSegment(); long withinOneDay = System.currentTimeMillis() - 24 * 60 * 60 * 1000; // Create a query with clauses using predefined keys and the retrieved values. KiiQuery query = new KiiQuery(KiiClause.and( KiiClause.equals("_owner", userId), KiiClause.or( KiiClause.equals("_version", 1), KiiClause.greaterThan("_created", withinOneDay)))); // Define how to output the query result. query.sortByAsc("_created"); query.setLimit(10); try { // Query KiiObjects. KiiQueryResult<KiiObject> result = bucket.query(query); List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with the first 10 KiiObjects. } } catch (IOException e) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
// Prepare the target bucket to be queried. KiiBucket bucket = Kii.bucket("AppBucket"); // Get values to use in query conditions. String userId = KiiUser.getCurrentUser().getID(); long withinOneDay = System.currentTimeMillis() - 24 * 60 * 60 * 1000; // Create a query with clauses using predefined keys and the retrieved values. KiiQuery query = new KiiQuery(KiiClause.and( KiiClause.equals("_owner", userId), KiiClause.or( KiiClause.equals("_version", 1), KiiClause.greaterThan("_created", withinOneDay)))); // Define how to output the query result. query.sortByAsc("_created"); query.setLimit(10); // Query KiiObjects. bucket.query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with the first 10 KiiObjects. } } }, query);
特定のフィールド名および型による検索
特定のフィールド名および型を指定した検索の例を挙げます。Object にはさまざまなカスタムフィールドを持たせることができ、名前と型が必ずしも一様ではなくなる可能性があります。hasField
句で検索対象を絞り込み、特定の型のフィールドを持つ Object のみを取得できます。
次のサンプルコードでは、省略可能な promotionalCode
フィールドを持つ Object のみを取得します。
-
// Create a query with a clause using a specific field and a type. KiiQuery hasField_query = new KiiQuery(KiiClause.hasField("promotionalCode",FieldType.String)); try { // Query KiiObjects. KiiQueryResult<KiiObject> result = Kii.bucket("AppBucket") .query(hasField_query); List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with KiiObjects in the result. } } catch (IOException e) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
// Create a query with a clause using a specific field and a type. KiiQuery hasField_query = new KiiQuery(KiiClause.hasField("promotionalCode",FieldType.String)); // Query KiiObjects. Kii.bucket("AppBucket") .query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } List<KiiObject> objLists = result.getResult(); for (KiiObject obj : objLists) { // Do something with KiiObjects in the result. } } }, hasField_query);
Not 句による検索
Not 句による検索の例を挙げます。長方形のエリアを指定して、その外部に位置する Object を検索します。
-
// Prepare the target bucket to be queried. KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); try { // Define a GeoBox clause with northeast and southwest points. GeoPoint sw = new GeoPoint(35.52105, 139.699402); GeoPoint ne = new GeoPoint(36.069082, 140.07843); KiiClause geoBoxClause = KiiClause.GeoBox("location", ne, sw); // Define a not clause with the Geobox clause. KiiClause notInTheBoxClause = KiiClause.not(geoBoxClause) // Create a query with the Not clause. KiiQuery query = new KiiQuery(notInTheBoxClause); // Query KiiObjects. KiiQueryResult<KiiObject> result = bucket.query(query); // Do something with the result. } catch (IOException ioe) { // Handle the error. } catch (AppException e) { // Handle the error. }
-
// Prepare the target bucket to be queried. KiiBucket bucket = KiiUser.getCurrentUser().bucket("myBucket"); // Define a GeoBox clause with northeast and southwest points. GeoPoint sw = new GeoPoint(35.52105, 139.699402); GeoPoint ne = new GeoPoint(36.069082, 140.07843); KiiClause geoBoxClause = KiiClause.GeoBox("location", ne, sw); // Define a not clause with the Geobox clause. KiiClause notInTheBoxClause = KiiClause.not(geoBoxClause) // Create a query with the Not clause. KiiQuery query = new KiiQuery(notInTheBoxClause); // Query KiiObjects. bucket.query(new KiiQueryCallBack<KiiObject>() { @Override public void onQueryCompleted(int token, KiiQueryResult<KiiObject> result, Exception exception) { if (exception != null) { // Handle the error. return; } // Do something with the result. } }, query);
not を含むクエリーでは、パフォーマンスが低下することがありますが、式の変形によって not の使用を回避できる場合があります。詳細は Not を含む式の変形 を参照してください。