検索のサンプルコード

さまざまな検索の例を以下に示します。

Bucket 内の全 Object の取得

まずは、もっとも単純な検索として Bucket 内の全ての Object を取得する例について説明します。この例では、すべての検索結果が一度に取得されることを想定しています。ページネーションなどは考慮していません。

Swift 3:

  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Create a query that returns all KiiObjects.
    let allQuery = KiiQuery(clause: nil)
    
    // Create a placeholder for any paginated queries.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      let results = try bucket.executeQuerySynchronous(allQuery, nextQuery: &nextQuery)
      // Do something with the result.
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Create a query that returns all KiiObjects.
    let allQuery = KiiQuery(clause: nil)
    
    // Create an array for storing all returned KiiObjects.
    var allResults = [Any]()
    
    // Query KiiObjects.
    bucket.execute(allQuery) { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Do something with the result.
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Create a query that returns all KiiObjects.
    KiiQuery *allQuery = [KiiQuery queryWithClause:nil];
    
    // Create a placeholder for any paginated queries.
    KiiQuery *nextQuery;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:allQuery
                                             withError:&error
                                               andNext:&nextQuery];
    if (error != nil) {
      // Handle the error.
      return;
    }
    // Do something with the result.
     
  • // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Create a query that returns all KiiObjects.
    KiiQuery *allQuery = [KiiQuery queryWithClause:nil];
    
    // Query KiiObjects.
    [bucket executeQuery:allQuery
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      // Do something with the result.
    }];

ここでは以下の処理が行われています。

  • KiiClause を何も指定せずに(例:nil 指定で)KiiQuery インスタンスを作成し、"all" 検索用のクエリインスタンスを作成。
  • このクエリインスタンスを、検索対象 Bucket の execute(_:_:) メソッドに渡して実行。

Bucket に対して "all" 検索を実施しているため、検索結果には Bucket 内の全ての Object が含まれます。

なお、期待どおりに取得できない場合、スコープの違い もご確認ください。

複数条件の検索

次に、以下の条件で検索を実行する例を取り上げます。

  • "gender" キーの値が "Female" であり、かつ "age" キーの値が 18 より大きい。
  • 結果を "age" キーの昇順でソート。
  • 一度の検索実行で取得する検索結果の最大件数を 10 件に設定。

Swift 3:

  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Define clauses.
    let clause1 = KiiClause.equals("gender", value: "Female")
    let clause2 = KiiClause.equals("age", value: NSNumber(value: 18 as Int))
    
    // Define an And clause with the above clauses.
    let totalClause = KiiClause.andClauses([clause1, clause2])
    
    // Create a query with the And clause.
    let query = KiiQuery(clause: totalClause)
    
    // Define how to output the query result.
    query.sort(byAsc: "age")
    query.limit = 10
    
    // Create an array for storing all returned KiiObjects.
    var allResults = [Any]()
    
    // Create a placeholder for any paginated queries.
    // If all the queried KiiObjects cannot be returned at once,
    // the placeholder will have a non-nil value that means
    // there is more data to retrieve.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      var results = try bucket.executeQuerySynchronous(query, nextQuery: &nextQuery)
    
      // Add the KiiObjects returned by this query to the "allResults" array.
      allResults.append(results as AnyObject)
    
      var nextQuery2 : KiiQuery?
    
      // If there is more data to retreive
      if nextQuery != nil {
        // Query the next 10 KiiObjects with pagination.
        results = try bucket.executeQuerySynchronous(nextQuery!, nextQuery: &nextQuery2)
    
        // Add the KiiObjects returned by this query to the "allResults" array.
        allResults.append(results as AnyObject)
      }
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Define clauses.
    let clause1 = KiiClause.equals("gender", value: "Female")
    let clause2 = KiiClause.equals("age", value: NSNumber(value: 18 as Int))
    
    // Define an And clause with the above clauses.
    let totalClause = KiiClause.andClauses([clause1, clause2])
    
    // Create a query with the And clause.
    let query = KiiQuery(clause: totalClause)
    
    // Define how to output the query result.
    query.sort(byAsc: "age")
    query.limit = 10
    
    // Create an array for storing all returned KiiObjects.
    var allResults = [Any]()
    
    // Query KiiObjects.
    bucket.execute(query) { (firstQuery : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Add the KiiObjects returned by this query to the "allResults" array.
      allResults.append(contentsOf: results!)
    
      // If there is more data to retreive
      if nextQuery != nil {
        // Query the next 10 KiiObjects with pagination.
        bucket.execute(nextQuery! , with: { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery2 , error : Error?) -> Void in
          if error != nil {
            // Handle the error.
            return
          }
    
          // Add the KiiObjects returned by this query to the "allResults" array.
          allResults.append(contentsOf: results!)
        })
      }
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Define clauses.
    KiiClause *clause1 = [KiiClause equals:@"gender"
                                     value:@"Female"];
    KiiClause *clause2 = [KiiClause greaterThan:@"age"
                                          value:[NSNumber numberWithInt:18]];
    
    // Define an And clause with the above clauses.
    KiiClause *totalClause = [KiiClause andClauses:@[clause1, clause2]];
    
    // Create a query with the And clause.
    KiiQuery *query = [KiiQuery queryWithClause:totalClause];
    
    // Define how to output the query result.
    [query sortByAsc:@"age"];
    [query setLimit:10];
    
    // Create an array for storing all returned KiiObjects.
    NSMutableArray *allResults = [NSMutableArray array];
    
    // Create a placeholder for any paginated queries.
    // If all the queried KiiObjects cannot be returned at once,
    // the placeholder will have a non-nil value that means
    // there is more data to retrieve.
    KiiQuery *nextQuery = nil;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:query
                                             withError:&error
                                               andNext:&nextQuery];
    if (error != nil) {
      // Handle the error.
      return;
    }
    
    // Add the KiiObjects returned by this query to the "allResults" array.
    [allResults addObjectsFromArray:results];
    
    // If there is more data to retrieve
    if (nextQuery != nil) {
      KiiQuery *nextQuery2 = nil;
    
      // Query the next 10 KiiObjects with pagination.
      results = [bucket executeQuerySynchronous:nextQuery
                                      withError:&error
                                        andNext:&nextQuery2];
      if (error != nil) {
        // Handle the error.
        return;
      }
    
      // Add the KiiObjects returned by this query to the "allResults" array.
      [allResults addObjectsFromArray:results];
    }
  • // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Define clauses.
    KiiClause *clause1 = [KiiClause equals:@"gender"
                                     value:@"Female"];
    KiiClause *clause2 = [KiiClause greaterThan:@"age"
                                          value:[NSNumber numberWithInt:18]];
    
    // Define an And clause with the above clauses.
    KiiClause *totalClause = [KiiClause andClauses:@[clause1, clause2]];
    
    // Create a query with the And clause.
    KiiQuery *query = [KiiQuery queryWithClause:totalClause];
    
    // Define how to output the query result.
    [query sortByAsc:@"age"];
    [query setLimit:10];
    
    // Create an array for storing all returned KiiObjects.
    NSMutableArray *allResults = [NSMutableArray array];
    
    // Query KiiObjects.
    [bucket executeQuery:query
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    
      // Add the KiiObjects returned by this query to the "allResults" array.
      [allResults addObjectsFromArray:results];
    
      // If there is more data to retrieve
      if (nextQuery != nil) {
        // Query the next 10 KiiObjects with pagination.
        [bucket executeQuery:nextQuery
                   withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
          if (error != nil) {
            // Handle the error.
            return;
          }
    
          // Add the KiiObjects returned by this query to the "allResults" array.
          [allResults addObjectsFromArray:results];
        }];
      }
    }];

ここでは以下の処理が行われています。

  • equals() メソッドと greaterThan() メソッドを用いて個々の検索条件を定義。さらにこれらの検索条件を andClauses(_:) メソッドで結合した KiiClause インスタンスを用いて KiiQuery インスタンスを作成。
  • KiiQuery インスタンスの sort(byAsc:) メソッドを実行して、ソート順序を指定。
  • KiiQuery インスタンスの limit プロパティにより、一度に取得する検索結果の最大件数を指定。
  • KiiQuery インスタンスを指定して検索対象 Bucket の execute(_:_:) メソッドを実行し、検索を実施。
  • KiiObject の NSArray として返却された検索結果をパース(今回の例では、検索結果を結果保存用の allResults にアペンド)。

今回の例では、ページネーションを考慮した検索結果のパースを行っています。

  • 検索結果のパース終了後、検索結果とともに返却された KiiQuery インスタンス(nextQuery)の内容を確認。
  • 返却された KiiQuery インスタンスが空ではない場合は、このインスタンスを指定して再度 execute(_:_:) メソッドを実行し、次の検索結果 10 件を含む KiiQueryResult インスタンスを取得。

位置情報による検索

次に、位置情報に基づく Object 検索を行う例を挙げます。

まず、以下のように "location" というフィールドに GeoPoint を持つ Object が存在するものとします。

Swift 3:

  • let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Create a KiiObject.
    let object = bucket.createObject()
    let point = KiiGeoPoint(latitude: 35.661561, andLongitude: 139.769595)
    object.setGeoPoint(point, forKey: "location")
    do{
      // Save the KiiObject.
      try object.saveSynchronous()
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Create a KiiObject.
    let object = bucket.createObject()
    let point = KiiGeoPoint(latitude: 35.661561, andLongitude: 139.769595)
    object.setGeoPoint(point, forKey: "location")
    
    // Save the KiiObject.
    object.save { (object : KiiObject?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
    }

Objective-C:

  • NSError *error = nil;
    
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Create a KiiObject.
    KiiObject *object = [bucket createObject];
    KiiGeoPoint *point = [[KiiGeoPoint alloc] initWithLatitude:35.661561
                                                  andLongitude:139.769595];
    [object setGeoPoint:point
                 forKey:@"location"];
    
    // Save the KiiObject.
    [object saveSynchronous:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
  • KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Create a KiiObject.
    KiiObject *object = [bucket createObject];
    KiiGeoPoint *point = [[KiiGeoPoint alloc] initWithLatitude:35.661561
                                                  andLongitude:139.769595];
    [object setGeoPoint:point
                 forKey:@"location"];
    
    // Save the KiiObject.
    [object saveWithBlock:^(KiiObject *object, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    }];

GeoBox(長方形エリア)による Object 検索を行うには、以下の様な処理を行います。

Swift 3:

  • // Prepare the target bucket to be queried.
    let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Define a GeoBox clause with northeast and southwest points.
    let sw = KiiGeoPoint(latitude: 35.658603, andLongitude: 139.745433)
    let ne = KiiGeoPoint(latitude: 36.069082, andLongitude: 140.07843)
    let clause = KiiClause.geoBox("location", northEast: sw, southWest: ne)
    
    // Create a query with the GeoBox clause.
    let query = KiiQuery(clause: clause)
    
    // Create a placeholder for any paginated queries.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      let results = try bucket.executeQuerySynchronous(query, nextQuery: &nextQuery)
      // Do something with the result.
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Prepare the target bucket to be queried.
    let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Define a GeoBox clause with northeast and southwest points.
    let sw = KiiGeoPoint(latitude: 35.658603, andLongitude: 139.745433)
    let ne = KiiGeoPoint(latitude: 36.069082, andLongitude: 140.07843)
    let clause = KiiClause.geoBox("location", northEast: sw, southWest: ne)
    
    // Create a query with the GeoBox clause.
    let query = KiiQuery(clause: clause)
    
    // Query KiiObjects.
    bucket.execute(query) { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Do something with the result.
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Define a GeoBox clause with northeast and southwest points.
    KiiGeoPoint *sw = [[KiiGeoPoint alloc] initWithLatitude:35.52105
                                               andLongitude:139.699402];
    KiiGeoPoint *ne = [[KiiGeoPoint alloc] initWithLatitude:36.069082
                                               andLongitude:140.07843];
    KiiClause *clause = [KiiClause geoBox:@"location"
                                northEast:ne
                                southWest:sw];
    
    // Create a query with the GeoBox clause.
    KiiQuery *query = [KiiQuery queryWithClause:clause];
    
    // Create a placeholder for any paginated queries.
    KiiQuery *next = nil;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:query
                                             withError:&error
                                               andNext:&next];
    if (error != nil) {
      // Handle the error.
      return;
    }
    // Do something with the result.
     
  • // Prepare the target bucket to be queried.
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Define a GeoBox clause with northeast and southwest points.
    KiiGeoPoint *sw = [[KiiGeoPoint alloc] initWithLatitude:35.52105
                                               andLongitude:139.699402];
    KiiGeoPoint *ne = [[KiiGeoPoint alloc] initWithLatitude:36.069082
                                               andLongitude:140.07843];
    KiiClause *clause = [KiiClause geoBox:@"location"
                                northEast:ne
                                southWest:sw];
    
    // Create a query with the GeoBox clause.
    KiiQuery *query = [KiiQuery queryWithClause:clause];
    
    // Query KiiObjects.
    [bucket executeQuery:query
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      // Do something with the result.
    }];

この例のように、GeoBox の検索条件は北東点と南西点を表す GeoPoint を指定して geoBox(_:northEast:southWest:) メソッドを実行することにより定義します。

次に、GeoDistance(円エリア)による Object 検索を行う処理例を以下に示します。この例では 2 つの GeoDistance を定義しており、これら 2 つの GeoDistance が交わるエリアにマッチする Object を検索しています。また、検索結果を片方の GeoDistance の中心点より近い順にソートしています。

Swift 3:

  • // Prepare the target bucket to be queried.
    let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Define the first GeoDistance clause.
    let center1 = KiiGeoPoint(latitude: 35.658603, andLongitude: 139.745433)
    let clause1 = KiiClause.geoDistance("location", center: center1, radius: 3000, putDistanceInto: "distance_from_center1")
    
    // Define the second GeoDistance clause.
    let center2 = KiiGeoPoint(latitude: 35.681382, andLongitude: 139.766084)
    let clause2 = KiiClause.geoDistance("location", center: center2, radius: 3000, putDistanceInto: nil)
    
    // Create a query with the GeoDistance clauses and set the sort order.
    let totalClause = KiiClause.andClauses([clause1, clause2])
    let query = KiiQuery(clause: totalClause)
    query.sort(byAsc: "_calculated.distance_from_center1")
    
    // Create an array for storing all returned KiiObjects.
    var allResults = [Any]()
    
    // Create a placeholder for any paginated queries.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      let results = try bucket.executeQuerySynchronous(query, nextQuery: &nextQuery)
    
      // Add the KiiObjects returned by this query to the "allResults" array.
      allResults.append(results as AnyObject)
    } catch let error as NSError {
      // Handle the error.
      return
    }
    
    // Get the distance from the center to the location.
    let retObject = allResults[0] as! KiiObject
    let retPoint = retObject.getForKey("location")
    let calc = retObject.getForKey("_calculated") as! NSDictionary
    let distance = calc.object(forKey: "distance_from_center1") as! NSDecimalNumber
  • // Prepare the target bucket to be queried.
    let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Define the first GeoDistance clause.
    let center1 = KiiGeoPoint(latitude: 35.658603, andLongitude: 139.745433)
    let clause1 = KiiClause.geoDistance("location", center: center1, radius: 3000, putDistanceInto: "distance_from_center1")
    
    // Define the second GeoDistance clause.
    let center2 = KiiGeoPoint(latitude: 35.681382, andLongitude: 139.766084)
    let clause2 = KiiClause.geoDistance("location", center: center2, radius: 3000, putDistanceInto: nil)
    
    // Create a query with the GeoDistance clauses and set the sort order.
    let totalClause = KiiClause.andClauses([clause1,clause2])
    let query = KiiQuery(clause: totalClause)
    query.sort(byAsc: "_calculated.distance_from_center1")
    
    // Create an array for storing all returned KiiObjects.
    var allResults = [Any]()
    
    // Query KiiObjects.
    bucket.execute(query) { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Add the KiiObjects returned by this query to the "allResults" array.
      allResults.append(contentsOf: results!)
    
      // Get the distance from the center to the location.
      let retObject = allResults[0] as! KiiObject
      let retPoint = retObject.getForKey("location")
      let calc = retObject.getForKey("_calculated") as! NSDictionary
      let distance = calc.object(forKey: "distance_from_center1") as! NSDecimalNumber
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Define the first GeoDistance clause.
    KiiGeoPoint *center1 = [[KiiGeoPoint alloc] initWithLatitude:35.658603
                                                    andLongitude:139.745433];
    KiiClause *clause1 = [KiiClause geoDistance:@"location"
                                         center:center1
                                         radius:3000
                                putDistanceInto:@"distance_from_center1"];
    
    // Define the second GeoDistance clause.
    KiiGeoPoint *center2 = [[KiiGeoPoint alloc] initWithLatitude:35.681382
                                                    andLongitude:139.766084];
    KiiClause *clause2 = [KiiClause geoDistance:@"location"
                                         center:center2
                                         radius:3000
                                putDistanceInto:nil];
    
    // Create a query with the GeoDistance clauses and set the sort order.
    KiiClause *totalClause = [KiiClause andClauses:@[clause1, clause2]];
    KiiQuery *query = [KiiQuery queryWithClause:totalClause];
    [query sortByAsc:@"_calculated.distance_from_center1"];
    
    // Create an array for storing all returned KiiObjects.
    NSMutableArray *allResults = [NSMutableArray array];
    
    // Create a placeholder for any paginated queries.
    KiiQuery *next = nil;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:query
                                             withError:&error
                                               andNext:&next];
    if (error != nil) {
      // Handle the error.
      return;
    }
    // Add the KiiObjects returned by this query to the "allResults" array.
    [allResults addObjectsFromArray:results];
    
    // Get the distance from the center to the location.
    KiiObject *retObj = [allResults objectAtIndex:0];
    KiiGeoPoint *retPoint = [retObj getGeoPointForKey:@"location"];
    NSDictionary* calc = [retObj getObjectForKey:@"_calculated"];
    NSDecimalNumber *distance = [calc objectForKey:@"distance_from_center1"];
  • // Prepare the target bucket to be queried.
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Define the first GeoDistance clause.
    KiiGeoPoint *center1 = [[KiiGeoPoint alloc] initWithLatitude:35.658603
                                                    andLongitude:139.745433];
    KiiClause *clause1 = [KiiClause geoDistance:@"location"
                                         center:center1
                                         radius:3000
                                putDistanceInto:@"distance_from_center1"];
    
    // Define the second GeoDistance clause.
    KiiGeoPoint *center2 = [[KiiGeoPoint alloc] initWithLatitude:35.681382
                                                    andLongitude:139.766084];
    KiiClause *clause2 = [KiiClause geoDistance:@"location"
                                         center:center2
                                         radius:3000
                                putDistanceInto:nil];
    
    // Create a query with the GeoDistance clauses and set the sort order.
    KiiClause *totalClause = [KiiClause andClauses:@[clause1, clause2]];
    KiiQuery *query = [KiiQuery queryWithClause:totalClause];
    [query sortByAsc:@"_calculated.distance_from_center1"];
    
    // Create an array for storing all returned KiiObjects.
    NSMutableArray *allResults = [NSMutableArray array];
    
    // Query KiiObjects.
    [bucket executeQuery:query
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      // Add the KiiObjects returned by this query to the "allResults" array.
      [allResults addObjectsFromArray:results];
    
      // Get the distance from the center to the location.
      KiiObject *retObj = [allResults objectAtIndex:0];
      KiiGeoPoint *retPoint = [retObj getGeoPointForKey:@"location"];
      NSDictionary* calc = [retObj getObjectForKey:@"_calculated"];
      NSDecimalNumber *distance = [calc objectForKey:@"distance_from_center1"];
    }];

ここでは以下の処理が行われています。

  • 中心点を表す GeoPoint、半径(メートル)、中心点からの距離格納用フィールド(オプショナル)を指定し、geoDistance(_:center:radius:putDistanceInto:) メソッドを実行して GeoDistance の検索条件を定義。
  • 2 つの GeoDistance を andClauses(_) メソッドで結合した KiiClause インスタンスを用いて KiiQuery インスタンスを作成。
  • KiiQuery インスタンスの sort(byAsc:) メソッドを実行して、ソート順序を指定。
  • KiiQuery インスタンスを指定して検索対象 Bucket の execute(_:_:) メソッドを実行し、検索を実施。
  • KiiObject の NSArray として返却された検索結果をパース(今回の例では、検索結果を結果保存用の allResults にアペンド)。

GeoDistance による検索を行った場合、検索にマッチした Object のそれぞれに対して、中心点からの距離(メートル)を Kii Cloud にセットさせることができます。今回の例では、GeoDistance1 の中心点からの距離を Kii Cloud にセットさせています。

  • 距離は getDistance(_:center:radius:putDistanceInto:) メソッド実行時に指定した距離格納用フィールド(今回の例では "distance_from_center1")にセットされます。
  • この距離を用いてソートを行う場合は、例のように "_calculated." の後に距離格納用フィールド名をアペンドした文字列を sort(byAsc:) メソッドに指定します。
  • 検索結果より距離を取得するには、例のように Object の "_calculated" フィールドを getObject(forKey:) メソッドで取得し、さらに object(forKey:) メソッドを実行して距離格納用フィールドより距離を取得します。

所定キーによる検索

次に、所定キーを検索条件に使った検索の例を挙げます。

次のコードでは、ログイン中のユーザーによって作成された Object のうち、更新されていないものと 1 日以内に作成されたものの両方を取得する条件で検索しています。ユーザー ID や作成日時はここに示すような方法で比較できます。

Swift 3:

  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Get values to use in query conditions.
    let userId = KiiUser.current()!.userID!
    let withinOneDay : Int64 = Int64(Date().timeIntervalSince1970 - 24 * 60 * 60) * 1000
    
    // Define clauses with predefined keys and the query conditions.
    let clause1 = KiiClause.equals("_owner", value: userId)
    let clause2 = KiiClause.equals("_version", value: NSNumber(value: 1 as Int))
    let clause3 = KiiClause.equals("_created", value: NSNumber(value: withinOneDay as Int64))
    
    // Define an And clause with the above clauses.
    let totalClause = KiiClause.andClauses([clause1, clause2, clause3])
    
    // Create a query with the And clause.
    let query = KiiQuery(clause: totalClause)
    
    // Define how to output the query result.
    query.sort(byAsc: "_created")
    query.limit = 10
    
    // Create a placeholder for any paginated queries.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      let results = try bucket.executeQuerySynchronous(query, nextQuery: &nextQuery)
      // Do something with the result.
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Get values to use in query conditions.
    let userId = KiiUser.current()!.userID!
    let withinOneDay : Int64 = Int64(Date().timeIntervalSince1970 - 24 * 60 * 60) * 1000
    
    // Define clauses with predefined keys and the query conditions.
    let clause1 = KiiClause.equals("_owner", value: userId)
    let clause2 = KiiClause.equals("_version", value: NSNumber(value: 1 as Int))
    let clause3 = KiiClause.equals("_created", value: NSNumber(value: withinOneDay as Int64))
    
    // Define an And clause with the above clauses.
    let totalClause = KiiClause.andClauses([clause1, clause2, clause3])
    
    // Create a query with the And clause.
    let query = KiiQuery(clause: totalClause)
    
    // Define how to output the query result.
    query.sort(byAsc: "_created")
    query.limit = 10
    
    // Query KiiObjects.
    bucket.execute(query) { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Do something with the result.
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Get values to use in query conditions.
    NSString* userId = [[KiiUser currentUser] userID];
    long long withinOneDay = (long long) (([[NSDate date] timeIntervalSince1970] - 24 * 60 * 60) * 1000);
    
    // Define clauses with predefined keys and the query conditions.
    KiiClause *clause1 = [KiiClause equals:@"_owner"
                                     value:userId];
    KiiClause *clause2 = [KiiClause equals:@"_version"
                                     value:[NSNumber numberWithInt:1]];
    KiiClause *clause3 = [KiiClause greaterThan:@"_created"
                                          value:[NSNumber numberWithLongLong:withinOneDay]];
    
    // Define an And clause with the above clauses.
    KiiClause *totalClause = [KiiClause andClauses:@[clause1,
                                                     [KiiClause orClauses:@[clause2,
                                                                            clause3]]]];
    
    // Create a query with the And clause.
    KiiQuery *query = [KiiQuery queryWithClause:totalClause];
    
    // Define how to output the query result.
    [query sortByAsc:@"_created"];
    [query setLimit:10];
    
    // Create a placeholder for any paginated queries.
    KiiQuery *nextQuery = nil;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:allQuery
                                             withError:&error
                                               andNext:&nextQuery];
    if (error != nil) {
      // Handle the error.
      return;
    }
    // Do something with the result.
     
  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Get values to use in query conditions.
    NSString* userId = [[KiiUser currentUser] userID];
    long long withinOneDay = (long long) (([[NSDate date] timeIntervalSince1970] - 24 * 60 * 60) * 1000);
    
    // Define clauses with predefined keys and the query conditions.
    KiiClause *clause1 = [KiiClause equals:@"_owner"
                                     value:userId];
    KiiClause *clause2 = [KiiClause equals:@"_version"
                                     value:[NSNumber numberWithInt:1]];
    KiiClause *clause3 = [KiiClause greaterThan:@"_created"
                                          value:[NSNumber numberWithLongLong:withinOneDay]];
    
    // Define an And clause with the above clauses.
    KiiClause *totalClause = [KiiClause andClauses:@[clause1,
                                                     [KiiClause orClauses:@[clause2,
                                                                            clause3]]]];
    
    // Create a query with the And clause.
    KiiQuery *query = [KiiQuery queryWithClause:totalClause];
    
    // Define how to output the query result.
    [query sortByAsc:@"_created"];
    [query setLimit:10];
    
    // Query KiiObjects.
    [bucket executeQuery:allQuery
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      // Do something with the result.
    }];

特定のフィールド名および型による検索

特定のフィールド名および型を指定した検索の例を挙げます。Object にはさまざまなカスタムフィールドを持たせることができ、名前と型が必ずしも一様ではなくなる可能性があります。hasField(_:andType:) 句で検索対象を絞り込み、特定の型のフィールドを持つ Object のみを取得できます。

次のサンプルコードでは、省略可能な promotionalCode フィールドを持つ Object のみを取得します。

Swift 3:

  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Create a clause with a specific field and a type.
    let hasFieldClause = KiiClause.hasField("promotionalCode", fieldType: .String)
    
    // Create a query with the above clause.
    let hasFieldQuery = KiiQuery(clause: hasFieldClause)
    
    // Create a placeholder for any paginated queries.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      let results = try bucket.executeQuerySynchronous(hasFieldQuery, nextQuery: &nextQuery)
      // Do something with the result.
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Prepare the target bucket to be queried.
    let bucket = Kii.bucket(withName: "AppBucket")
    
    // Create a clause with a specific field and a type.
    let hasFieldClause = KiiClause.hasField("promotionalCode", fieldType: .String)
    
    // Create a query with the above clause.
    let hasFieldQuery = KiiQuery(clause: hasFieldClause)
    
    // Query KiiObjects.
    bucket.execute(hasFieldQuery) { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Do something with the result.
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Create a clause with a specific field and a type.
    KiiClause *hasFieldclause = [KiiClause hasField:@"promotionalCode"
                                     fieldType:KiiFieldTypeString];
    
    // Create a query with the above clause.
    KiiQuery *hasFieldQuery = [KiiQuery queryWithClause:hasFieldclause];
    
    // Create a placeholder for any paginated queries.
    KiiQuery *nextQuery;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:hasFieldQuery
                                             withError:&error
                                               andNext:&nextQuery];
    if (error != nil) {
      // Handle the error.
      return;
    }
    // Do something with the result.
     
  • // Prepare the target bucket to be queried.
    KiiBucket *bucket = [Kii bucketWithName:@"AppBucket"];
    
    // Create a clause with a specific field and a type.
    KiiClause *hasFieldClause = [KiiClause hasField:@"promotionalCode"
                                     fieldType:KiiFieldTypeString];
    
    // Create a query with the above clause.
    KiiQuery *hasFieldQuery = [KiiQuery queryWithClause:hasFieldClause];
    
    // Query KiiObjects.
    [bucket executeQuery:hasFieldQuery
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      // Do something with the result.
    }];

Not 句による検索

Not 句による検索の例を挙げます。長方形のエリアを指定して、その外部に位置する Object を検索します。

Swift 3:

  • // Prepare the target bucket to be queried.
    let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Define a GeoBox clause with northeast and southwest points.
    let sw = KiiGeoPoint(latitude: 35.658603, andLongitude: 139.745433)
    let ne = KiiGeoPoint(latitude: 36.069082, andLongitude: 140.07843)
    let notInTheBoxClause = KiiClause.geoBox("location", northEast: sw, southWest: ne)
    
    // Define a not clause with the Geobox clause.
    let notInTheBoxClause = KiiClause.notClause(geoBoxClause)
    
    // Create a query with the Not clause.
    let query = KiiQuery(clause: notInTheBoxClause)
    
    // Create a placeholder for any paginated queries.
    var nextQuery : KiiQuery?
    
    do{
      // Query KiiObjects.
      let results = try bucket.executeQuerySynchronous(query, nextQuery: &nextQuery)
      // Do something with the result.
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Prepare the target bucket to be queried.
    let user = KiiUser.current()!
    let bucket = user.bucket(withName: "MyBucket")
    
    // Define a GeoBox clause with northeast and southwest points.
    let sw = KiiGeoPoint(latitude: 35.658603, andLongitude: 139.745433)
    let ne = KiiGeoPoint(latitude: 36.069082, andLongitude: 140.07843)
    let notInTheBoxClause = KiiClause.geoBox("location", northEast: sw, southWest: ne)
    
    // Define a Not clause with the Geobox clause.
    let notInTheBoxClause = KiiClause.notClause(geoBoxClause)
    
    // Create a query with the Not clause.
    let query = KiiQuery(clause: notInTheBoxClause)
    
    // Query KiiObjects.
    bucket.execute(query) { (query : KiiQuery?, bucket : KiiBucket, results : [Any]?, nextQuery : KiiQuery?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
      // Do something with the result.
    }

Objective-C:

  • NSError *error = nil;
    
    // Prepare the target bucket to be queried.
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Define a GeoBox clause with northeast and southwest points.
    KiiGeoPoint *sw = [[KiiGeoPoint alloc] initWithLatitude:35.52105
                                               andLongitude:139.699402];
    KiiGeoPoint *ne = [[KiiGeoPoint alloc] initWithLatitude:36.069082
                                               andLongitude:140.07843];
    KiiClause *geoBoxclause = [KiiClause geoBox:@"location"
                               northEast:ne
                               southWest:sw];
    
    // Define a not clause with the Geobox clause.
    KiiClause *notInTheBoxClause = [KiiClause notClause:geoBoxclause];
    
    // Create a query with the Not clause.
    KiiQuery *query = [KiiQuery queryWithClause:notInTheBoxClause];
    
    // Create a placeholder for any paginated queries.
    KiiQuery *next = nil;
    
    // Query KiiObjects.
    NSArray *results = [bucket executeQuerySynchronous:query
                                             withError:&error
                                               andNext:&next];
    if (error != nil) {
      // Handle the error.
      return;
    }
    // Do something with the result.
     
  • // Prepare the target bucket to be queried.
    KiiUser *user = [KiiUser currentUser];
    KiiBucket *bucket = [user bucketWithName:@"MyBucket"];
    
    // Define a GeoBox clause with northeast and southwest points.
    KiiGeoPoint *sw = [[KiiGeoPoint alloc] initWithLatitude:35.52105
                                               andLongitude:139.699402];
    KiiGeoPoint *ne = [[KiiGeoPoint alloc] initWithLatitude:36.069082
                                               andLongitude:140.07843];
    KiiClause *geoBoxclause = [KiiClause geoBox:@"location"
                                northEast:ne
                                southWest:sw];
    
    // Define a not clause with the Geobox clause.
    KiiClause *notInTheBoxClause = [KiiClause notClause:geoBoxclause];
    
    // Create a query with the Not clause.
    KiiQuery *query = [KiiQuery queryWithClause:notInTheBoxClause];
    
    // Query KiiObjects.
    [bucket executeQuery:query
               withBlock:^(KiiQuery *query, KiiBucket *bucket, NSArray *results, KiiQuery *nextQuery, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      // Do something with the result.
    }];

notClause(:_) を含むクエリーでは、パフォーマンスが低下することがありますが、式の変形によって notClause(_:) の使用を回避できる場合があります。詳細は Not を含む式の変形 を参照してください。