検索のサンプルコード

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

Bucket 内の全 Object の取得

まずは、最も単純な例として、Bucket 内の全てのオブジェクトを取得する検索を考えます。

全オブジェクト取得のためには、"all" 検索に相当する KiiQuery インスタンスを作成します。これは KiiQuery.queryWithClause() を何の KiiClause オブジェクトも渡さずに実行することにより実現できます。検索対象 Bucket の executeQuery() メソッドを、作成した "all" クエリを渡して実行すると、Bucket 内の全てのオブジェクトが返されます。別の方法として、クエリとして null を指定して executeQuery() メソッドを実行しても同じ結果となります。

  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Create a query that returns all KiiObjects.
    var allQuery = KiiQuery.queryWithClause();
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Execute another query to get more KiiObjects.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, allQuery, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Create a query that returns all KiiObjects.
    var allQuery = KiiQuery.queryWithClause();
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i = 0; i < resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Execute another query to get more KiiObjects.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(allQuery, queryCallbacks);
    // Alternatively, you can use:
    // bucket.executeQuery(null, queryCallbacks);

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

複数条件の検索

次に、以下の条件でオブジェクトを検索するケースを考えます。

  • "gender" プロパティが "Female"、かつ "age" が 18 より大きい
  • 検索結果の並びは、"age" プロパティの値で昇順にソートされている
  • 10 件ごと取得する

次のコードは上記条件のクエリを構築します。

  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Define clauses.
    var clause1 = KiiClause.equals("gender", "Female");
    var clause2 = KiiClause.greaterThan("age", 18);
    
    // Define an And clause with the above clauses.
    var totalClause = KiiClause.and(clause1, clause2);
    
    // Create a query with the And clause.
    var query = KiiQuery.queryWithClause(totalClause);
    
    // Define how to output the query result.
    query.setLimit(10);
    query.sortByAsc("age");
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Query the next 10 KiiObjects with pagination.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, query, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Define clauses.
    var clause1 = KiiClause.equals("gender", "Female");
    var clause2 = KiiClause.greaterThan("age", 18);
    
    // Define an And clause with the above clauses.
    var totalClause = KiiClause.and(clause1, clause2);
    
    // Create a query with the And clause.
    var query = KiiQuery.queryWithClause(totalClause);
    
    // Define how to output the query result.
    query.setLimit(10);
    query.sortByAsc("age");
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i=0; i<resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Query the next 10 KiiObjects with pagination.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(query, queryCallbacks);

位置情報による検索

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

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

  • // Create a KiiObject.
    var obj = KiiUser.getCurrentUser().bucketWithName("MyBucket").createObject();
    var point = KiiGeoPoint.geoPoint(35.661561, 139.769595);
    obj.setGeoPoint("location",point);
    
    // Save the KiiObject.
    obj.save().then(
      function(theObject) {
        // Do something.
      }
    ).catch(
      function(error) {
        var theObject = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Create a KiiObject.
    var obj = KiiUser.getCurrentUser().bucketWithName("MyBucket").createObject();
    var point = KiiGeoPoint.geoPoint(35.661561, 139.769595);
    obj.setGeoPoint("location",point);
    
    // Save the KiiObject.
    obj.save({
      success: function(theObject) {
        // Do something.
      },
      failure: function(theObject, errorString) {
        // Handle the error.
      }
    });

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

  • // Prepare the target bucket to be queried.
    var bucket = KiiUser.getCurrentUser().bucketWithName("MyBucket");
    
    // Define a GeoBox clause with northeast and southwest points.
    var ne = KiiGeoPoint.geoPoint(36.069082, 140.07843);
    var sw = KiiGeoPoint.geoPoint(35.52105, 139.699402);
    var clause = KiiClause.geoBox('location', ne, sw);
    
    // Create a query with the GeoBox clause.
    var query = KiiQuery.queryWithClause(clause);
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Execute another query to get more KiiObjects.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, query, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = KiiUser.getCurrentUser().bucketWithName("MyBucket");
    
    // Define a GeoBox clause with northeast and southwest points.
    var ne = KiiGeoPoint.geoPoint(36.069082, 140.07843);
    var sw = KiiGeoPoint.geoPoint(35.52105, 139.699402);
    var clause = KiiClause.geoBox('location', ne, sw);
    
    // Create a query with the GeoBox clause.
    var query = KiiQuery.queryWithClause(clause);
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i = 0; i < resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Execute another query to get more KiiObjects.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(query, queryCallbacks);

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

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

  • // Prepare the target bucket to be queried.
    var bucket = KiiUser.getCurrentUser().bucketWithName("MyBucket");
    
    // Define the first GeoDistance clause.
    var center1 = KiiGeoPoint.geoPoint(35.658603, 139.745433);
    var clause1 = KiiClause.geoDistance('location', center1, 3000, "distance_from_center1");
    
    // Define the second GeoDistance clause.
    var center2 = KiiGeoPoint.geoPoint(35.681382, 139.766084);
    var clause2 = KiiClause.geoDistance('location', center2, 3000, "distance_from_center2");
    
    // Define an And clause with the above clauses.
    var intersectionClause = KiiClause.and(clause1, clause2);
    
    // Create a query with the GeoDistance clauses and set the sort order.
    var query = KiiQuery.queryWithClause(intersectionClause);
    query.sortByAsc("_calculated.distance_from_center1");
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Execute another query to get more KiiObjects.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, query, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
        // Check the first location.
        var obj = records[i];
        var point = obj.getGeoPoint("location");
    
        // Get the distance from the center to the location.
        var calculated = obj.get("_calculated");
        var distance = calculated["distance_from_center1"];
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = KiiUser.getCurrentUser().bucketWithName("MyBucket");
    
    // Define the first GeoDistance clause.
    var center1 = KiiGeoPoint.geoPoint(35.658603, 139.745433);
    var clause1 = KiiClause.geoDistance('location', center1, 3000, "distance_from_center1");
    
    // Define the second GeoDistance clause.
    var center2 = KiiGeoPoint.geoPoint(35.681382, 139.766084);
    var clause2 = KiiClause.geoDistance('location', center2, 3000, "distance_from_center2");
    
    // Define an And clause with the above clauses.
    var intersectionClause = KiiClause.and(clause1, clause2);
    
    // Create a query with the GeoDistance clauses and set the sort order.
    var query = KiiQuery.queryWithClause(intersectionClause);
    query.sortByAsc("_calculated.distance_from_center1");
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i = 0; i < resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
          // Check the first location.
          var obj = resultSet[i];
          var point = obj.getGeoPoint("location");
    
          // Get the distance from the center to the location.
          var calculated = obj.get("_calculated");
          var distance = calculated["distance_from_center1"];
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Execute another query to get more KiiObjects.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(query, queryCallbacks);

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

  • 中心点を表す GeoPoint、半径(メートル)、中心点からの距離格納用フィールド(オプショナル)を指定して geoDistance() メソッドを実行し、GeoDistance の検索条件を定義。
  • 2 つの GeoDistance を and() メソッドで結合した KiiClause インスタンスを用いて KiiQuery インスタンスを作成。
  • KiiQuery インスタンスの sortByAsc() メソッドを実行して、ソート順序を指定。
  • KiiQuery インスタンスを指定して検索対象 Bucket の executeQuery() メソッドを実行し、検索を実施。
  • 検索結果をパース。

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

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

所定キーによる検索

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

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

  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Get values to use in query conditions.
    var userId = KiiUser.getCurrentUser().getID()
    var withinOneDay = new Date().getTime() - 24 * 60 * 60 * 1000;
    
    // Create a query with clauses using predefined keys and the retrieved values.
    var query = KiiQuery.queryWithClause(KiiClause.and(
          KiiClause.equals("_owner", userId),
          KiiClause.or(
              KiiClause.equals("_version", 1),
              KiiClause.greaterThan("_created", withinOneDay))));
    
    // Define how to output the query result.
    query.setLimit(10);
    query.sortByAsc("_created");
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Query the next 10 KiiObjects with pagination.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, query, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Get values to use in query conditions.
    var userId = KiiUser.getCurrentUser().getID()
    var withinOneDay = new Date().getTime() - 24 * 60 * 60 * 1000;
    
    // Create a query with clauses using predefined keys and the retrieved values.
    var query = KiiQuery.queryWithClause(KiiClause.and(
          KiiClause.equals("_owner", userId),
          KiiClause.or(
              KiiClause.equals("_version", 1),
              KiiClause.greaterThan("_created", withinOneDay))));
    
    // Define how to output the query result.
    query.setLimit(10);
    query.sortByAsc("_created");
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i = 0; i < resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Query the next 10 KiiObjects with pagination.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(query, queryCallbacks);

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

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

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

  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Create a query with a clause using a specific field and a type.
    var hasFieldQuery = KiiQuery.queryWithClause(KiiClause.hasField("promotionalCode","STRING"));
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Execute another query to get more KiiObjects.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, hasField, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = Kii.bucketWithName("AppBucket");
    
    // Create a query with a clause using a specific field and a type.
    var hasFieldQuery = KiiQuery.queryWithClause(KiiClause.hasField("promotionalCode","STRING"));
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i = 0; i < resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Execute another query to get more KiiObjects.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(hasFieldQuery, queryCallbacks);

Not 句による検索

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

  • // Prepare the target bucket to be queried.
    var bucket = KiiUser.getCurrentUser().bucketWithName("MyBucket");
    
    // Define a GeoBox clause with northeast and southwest points.
    var ne = KiiGeoPoint.geoPoint(36.069082, 140.07843);
    var sw = KiiGeoPoint.geoPoint(35.52105, 139.699402);
    var geoBoxClause = KiiClause.geoBox('location', ne, sw);
    
    // Define a not clause with the Geobox clause.
    var notInTheBoxClause = KiiClause.not(geoBoxclause);
    
    // Create a query with the not clause.
    var query = KiiQuery(notInTheBoxClause);
    
    function queryAll(bucket, query, userProc) {
      var queryRecurr = function(params) {
        var queryPerformed = params[0];
        var resultSet = params[1];
        var nextQuery = params[2];
    
        userProc(resultSet);
        if (nextQuery == null) {
          return Promise.resolve();
        }
        // There is more data to retrieve.
        // Execute another query to get more KiiObjects.
        return bucket.executeQuery(nextQuery).then(queryRecurr);
      };
      return bucket.executeQuery(query).then(queryRecurr);
    }
    
    // Query KiiObjects.
    queryAll(bucket, query, function(records) {
      // Do something with the result.
      for (var i = 0; i < records.length; i++) {
        // Do something with the KiiObject at resultSet[i].
      }
    }).catch(
      function(error) {
        var theBucket = error.target;
        var errorString = error.message;
        // Handle the error.
      }
    );
  • // Prepare the target bucket to be queried.
    var bucket = KiiUser.getCurrentUser().bucketWithName("MyBucket");
    
    // Define a GeoBox clause with northeast and southwest points.
    var ne = KiiGeoPoint.geoPoint(36.069082, 140.07843);
    var sw = KiiGeoPoint.geoPoint(35.52105, 139.699402);
    var geoBoxClause = KiiClause.geoBox('location', ne, sw);
    
    // Define a not clause with the Geobox clause.
    var notInTheBoxClause = KiiClause.not(geoBoxclause);
    
    // Create a query with the not clause.
    var query = KiiQuery(notInTheBoxClause);
    
    // Define callback functions.
    var queryCallbacks = {
      success: function(queryPerformed, resultSet, nextQuery) {
        // Do something with the result.
        for (var i = 0; i < resultSet.length; i++) {
          // Do something with the KiiObject at resultSet[i].
        }
        // If there is more data to retrieve
        if (nextQuery != null) {
          // Execute another query to get more KiiObjects.
          bucket.executeQuery(nextQuery, queryCallbacks);
        }
      },
      failure: function(queryPerformed, errorString) {
        // Handle the error.
      }
    }
    
    // Query KiiObjects.
    bucket.executeQuery(query, queryCallbacks);

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