Query Examples
See the following examples of various queries:
- Querying all KiiObjects in a bucket
- Querying with multiple conditions
- Querying with geolocation data
- Querying with predefined keys
- Querying with a specific field name and a field type
- Querying with a not clause
Querying all KiiObjects in a bucket
Let us start with the simplest example: querying all KiiObjects in a bucket.
-
// 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);
Here is what is happening in the sample code:
- Creates a
KiiQuery
instance without aKiiClause
instance. This query will get all KiiObjects. - Queries KiiObjects by calling the
query()
method in the target bucket by passing the query instance. Alternatively, you can call the method with a value of null. - Parses the query results returned as a
KiiQueryResult
instance by calling thegetResult()
method.
Executing an "all" query in a bucket will return all KiiObjects in it.
If you cannot get the expected result, check if you are querying the bucket in the correct scope (See here for more discussion).
Querying with multiple conditions
Next, let's query KiiObjects with the following conditions:
- The field "gender" has a value of "Female".
- The field "age" has a value greater than 18.
- Sort the query results in ascending order by the field "age".
- Limit the number of query results returned per call to 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);
Here is what is happening in the sample code:
- Creates query conditions by calling the
equals()
andgreaterThan()
methods. Then creates aKiiClause
instance by concatenating these two conditions with theand()
method. Finally, the code creates aKiiQuery
instance with thisKiiClause
instance. - Calls the
sortByAsc()
method of theKiiQuery
instance to define the sort order. - Calls the
setLimit()
method of theKiiQuery
instance to define the maximum number of KiiObjects returned in each query result set. - Queries KiiObjects by calling the
query()
method in the target bucket by passing the query instance. - Parses the query results returned as a
KiiQueryResult
instance by calling thegetResult()
method.
In this example, query results are parsed in consideration of pagination:
- After parsing through the query results, the
hasNext()
method of theKiiQueryResult
checks if more KiiObjects are available. - If there are more KiiObjects, the
getNextQueryResult()
method gets a newKiiQueryResult
instance that contains the next 10 KiiObjects.
Querying with geolocation data
Let us now see how to query using geolocation data as a query condition.
Suppose that a KiiObject has a field named "location" whose value is a GeoPoint
object as shown in the following sample code:
-
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; } } });
Here is an example that queries KiiObjects within a rectangle area using a GeoBox()
clause.
-
// 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);
As shown in the sample code, you define a GeoBox()
clause by calling the geoBox()
method with two GeoPoints, one representing the northeast point, and another one representing the southwest point.
Here is an example of querying KiiObjects within a circular area using a GeoDistance()
clause. In this example, we will query KiiObjects that are in the area overlapped by two GeoDistances (GeoDistance1 and GeoDistance2). We will also sort query results in ascending order by the distance from GeoDistance1's center point.
-
// 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);
Here is what is happening in the sample code:
- Defines two GeoDistance query conditions by calling the
geoDistance()
method. Here we specify a GeoPoint representing the center, a radius in meters, and optionally a field that stores the distance between the center of the circular area and a returned KiiObject. Kii Cloud will use this field in a query response. - Creates a
KiiClause
instance by concatenating two GeoDistance query conditions via theand()
method. Then creates aKiiQuery
instance using thisKiiClause
instance. - Calls the
sortByAsc()
method of theKiiQuery
instance to set the sort order. - Queries KiiObjects by calling the
query()
method of the target bucket by passing the query instance. - Parses the query results by calling the
getResult()
method of theKiiQueryResult
instance.
With a GeoDistance query condition, Kii Cloud can return the distance between the center point of a GeoPoint and each returned KiiObject. In this example, the distance between GeoDistance1's center point and KiiObjects are returned.
- The distance will be stored in the field specified when the
geoDistance()
method is called (the "distance_from_center1" field in this example). - To sort query results by distance, call the
sortByAsc()
method with a string "_calculated." followed by the name of the distance field. - To get the distance, get the value (JSONObject) of the "_calculated" field by calling the
getJSONObject()
method, and then call thegetDouble()
method of the distance field.
Querying with predefined keys
Now, let us show an example of querying with predefined keys.
The next sample code gets KiiObjects that are owned by the current user and are either not updated after creation or updated within a day.
-
// 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);
Querying with a specific field name and a field type
Now, let us show an example of querying with a specific field name and a field type. KiiObjects can have various custom fields that are not always consistent. By using a hasField()
clause, we can narrow the results to KiiObjects that have a specific field of a specific data type.
The next sample code gets KiiObjects that have an optional promotionalCode
field.
-
// 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);
Querying with a not clause
Now, let us show an example of querying with a not()
clause. This time, we will query KiiObjects that are outside a specified rectangle area.
-
// 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);
Querying with a not()
clause can decrease performance but you might be able to transform the clause to avoid a not operator. See Transforming a not clause for more information.