計算モデル

計算モデルは仮想的なモデルで、他のモデルや外部リソースのデータを処理するときに作成されます。データの処理と保存は、データベースではなく、App Maker サーバーまたはクライアントで行われます。

計算モデルでは次の操作が可能です。

  • 別のモデルのデータからカスタム レポートを合成する
  • 外部のウェブサービスからデータを取得する

計算モデルの種類

App Maker には、3 種類の計算モデルがあります。

  • SQL 計算モデル: このモデルは、アプリの Cloud SQL データベースに SQL クエリを送信し、レコードを生成します。詳しくは、SQL 計算モデルをご覧ください。
  • 計算モデル: このモデルは、サーバーサイドのクエリ スクリプトを使用して処理を行い、レコードの配列を返します。詳しくは、クエリ スクリプトをご覧ください。
  • クライアント サイドの計算モデル: このモデルは、クライアント サイドのクエリ スクリプトを使用して、データを同期的に取得します。コールバックを使用して結果を非同期で返すこともできます。

クライアント サイドの計算モデル

クライアント サイドの計算モデルは、通常のデータソース クエリの代わりにカスタムクエリ スクリプトを実行し、クエリ パラメータから任意のフィルタに渡します。

カスタムクエリ スクリプトを使用するには:

  1. クライアント サイドの計算モデルの [Datasources] タブに移動します。
  2. [Query] コードボックスに、カスタムクエリ スクリプトを入力します。スクリプトには return ステートメントを含める必要があります。
  3. サードパーティのサービスから取得したデータをレンダリングするには:
    1. スクリプト クエリをサードパーティの API クエリとマッピングします。
    2. 返されたデータとモデルレコードをマッピングします。

モデルの選択

次の表と計算モデルの制限を参考にして、最適なモデルタイプを選択してください。

目的 使用するモデル
アプリのモデルからデータを再構築する。 SQL 計算モデルまたは計算モデル(サーバーサイド)

既存モデルの多くのフィールドが計算モデルで使用されている場合は、サーバーサイドの計算モデルではなく、クエリ データソースを使用します。通常、クエリ データソースのほうが簡単です。

API とクライアント サイド ライブラリを使用してデータを取得する。 クライアント サイドの計算モデル

このモデルでは、Google API またはサードパーティ サービス(Facebook SDK や SalesForce API など)を使用してデータを取得できます。

サーバーにクエリを送信することなく、チャートや動的メニューなどのアプリのコンポーネントをすばやく表示する。 クライアント サイドの計算モデル

制限事項

サーバーサイドの計算モデルの制限事項:

  • レコードは読み取り専用です。変更や削除はできません。
  • クライアントでレコードを作成することはできません。
  • App Maker モデルとのリレーションは設定できません。
  • SQL 計算モデルのクエリに、照会先のモデルに設定されたセキュリティ制限は適用されません。SQL 計算モデル自体のセキュリティ制限は [Security] タブで設定します。

クライアント サイトの計算モデルの制限事項:

  • レコードは読み取り専用です。変更や削除はできません。
  • App Maker モデルとのリレーションは設定できません。
  • ページングや並べ替えの構成はサポートされません。
  • イベントやセキュリティの構成はサポートされません。
  • 二重のコールバックや戻り時のコールバックなど、結果が複数回返される場合はエラーが返されます。

計算モデルの例

SQL 計算モデル

SQL 計算モデルの例については、Cloud SQL をご覧ください。

サーバーサイドのクエリ スクリプト

次のクエリ スクリプトでは、Employee モデルの Location フィールドを使用して、勤務地ごとの従業員数を計算します。

var calculatedModelRecords = [];
    var recordsByLocation = {};
    var allEmployees = app.models.Employee.newQuery().run();
    for (var i = 0; i < allEmployees.length; i++) {
      var employee = allEmployees[i];
      if (!recordsByLocation[employee.Location]) {
        var calculatedModelRecord = app.models.EmployeesByLocation.newRecord();
        calculatedModelRecord.NumberOfEmployees = 1;
        calculatedModelRecord.Location = employee.Location;
        calculatedModelRecords.push(calculatedModelRecord);
        recordsByLocation[employee.Location] = calculatedModelRecord;
      } else {
        recordsByLocation[employee.Location].NumberOfEmployees++;
      }
    }
    return calculatedModelRecords;
    

このスクリプトは、Employee モデルの各レコードを繰り返し処理し、次のことを行います。

  1. 新しい勤務地が見つかるたびにレコードを作成します。
  2. 同じ勤務地のレコードが見つかるたびに従業員数を増やします。

このスクリプトは newRecord() を使用して計算モデルのレコードを作成しますが、データ バックエンドにレコードは作成されません。レコードは直接クライアントに返されます。

その他の例については、クエリ スクリプトをご覧ください。

クライアント サイドの計算モデル

例 1: App Maker Client API の同期クエリ

次のスクリプトはフィボナッチ数列を返します。結果が返されるまで、他の App Maker のオペレーションは待機します。

  var limit = 10;
      var result = [];
      for (var i=0; i < limit; i++) {
        var record =  recordFactory.create();
        if (i < 2) {
          record.Value = 1;
        } else {
          record.Value = result[i-1].Value + result[i-2].Value;
        }
        result.push(record);
      }
      return result;
    

例 2: サードパーティ API への非同期リクエスト

次のスクリプトは、Google ブックスの API を使用して、ユーザーの入力(SearchString)と一致する本を検索し、結果をコールバック関数で返します。

// Note: Include JQuery library for the application
    // Search for a book matching the user's search string
    var searchString = query.parameters.SearchString;
    $.getJSON('https://www.googleapis.com/books/v1/volumes?q=' + encodeURI(searchString), function(result){
      var records = result.items.map(function(bookData){
        // Create a record from the book's data
        var record = recordFactory.create();
        record.Title = bookData.volumeInfo.title || null;
        return record;
      });
      // Return results
      callback.success(records);
    });
    

例 3: 成功 / 失敗を返すコールバック関数を使用した App Maker Client API 非同期クエリ

次のスクリプトは、すぐに必要でない結果を非同期で返します。

  externalApi.execute(function(results) {
        if (results.length) {
          сallback.success(mapResultsToRecords(results));
        } else {
          сallback.failure(‘No results were found');
        }
      });