App Engine Datastore から Datastore モードの Firestore に移行する

このガイドでは、App Engine Datastore から Datastore モードの Firestore(Datastore とも呼ばれます)に移行する方法について説明します。

Datastore モードの Firestore は、App Engine Datastore と類似しており、両方とも基盤となる Datastore サービスを参照します。App Engine Datastore には App Engine の以前のバンドル サービスからのみアクセスできますが、Datastore モードの Firestore はスタンドアロンの Google Cloud プロダクトであり、Cloud クライアント ライブラリからアクセスします。

Datastore モードの Firestore では無料枠も用意されており、スケーラビリティの高い NoSQL ドキュメント データベースを管理できます。これにより、今後 Cloud Run や他の Google Cloud アプリ ホスティング プラットフォームに柔軟に移行できます。

始める前に

  1. さまざまな Firestore データベース モードを確認して、アプリに最適なユースケースを理解してください。このガイドでは、Datastore モードへの移行方法について説明します。

  2. Datastore モードの Firestore の料金割り当てを確認して理解してください。

    Datastore モードの Firestore では、無料の使用量(1 日の上限あり)と、有料アカウントについては無制限のストレージ、読み取り、書き込みオペレーションをご利用いただけます。App Engine アプリを無効にしている間は、トラフィックが発生しないため料金は発生しませんが、無料の割り当て上限を超えると、Datastore の使用に対して課金される場合があります。

  3. アプリを含むプロジェクトで次の API を有効にします。

    • ビルド アーティファクトを保存、管理するための Artifact Registry API
    • アプリケーションを継続的にビルド、テスト、デプロイするための Cloud Build API。
    • App Engine バンドルの Datastore から Datastore モードの Firestore に移行するための Cloud Datastore API。

      API の有効化

  4. Java 8 または 11 を実行する既存の App Engine アプリを App Engine Datastore サービスに接続している。

プロセスの概要

App Engine Datastore から Datastore モードの Firestore に移行するプロセスは、大まかに次の手順で構成されます。

  1. 構成ファイルを更新する
  2. Java アプリを更新する
    1. インポート ステートメントを更新する
    2. アプリが Datastore サービスにアクセスする方法を変更する
    3. Datastore で生成されたキーを取得する
    4. エンティティ作成の変更
  3. トランザクションを commit する
  4. クエリ結果

構成ファイルを更新する

Datastore モードのクライアント ライブラリを使用するように構成ファイルを更新します。

ベースライン Java アプリの pom.xml ファイルを更新します。

  1. 次のように、App Engine SDK の appengine-api-1.0-sdk インポートを削除します。

    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-1.0-sdk</artifactId>
      <version>2.0.4</version>
    </dependency>
    
  2. 次のように Datastore クライアントを追加します。

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-datastore</artifactId>
      <!-- Use latest version -->
      <version>2.2.9</version>
    </dependency>
    

Java アプリを更新する

import ステートメントを更新する

インポートの行と初期化の行を更新してアプリケーション ファイルを変更します。

  1. App Engine Datastore com.google.appengine.api.datastore.* の次の App Engine import ステートメントを削除します。

      import com.google.appengine.api.datastore.DatastoreService;
      import com.google.appengine.api.datastore.DatastoreServiceFactory;
      import com.google.appengine.api.datastore.Entity;
      import com.google.appengine.api.datastore.FetchOptions;
      import com.google.appengine.api.datastore.Query;
    
  2. Datastore モードの com.google.cloud.datastore.* インポートの次の Firestore を追加します。

      import com.google.cloud.Timestamp;
      import com.google.cloud.datastore.Datastore;
      import com.google.cloud.datastore.DatastoreOptions;
      import com.google.cloud.datastore.Entity;
      import com.google.cloud.datastore.Key;
      import com.google.cloud.datastore.FullEntity;
      import com.google.cloud.datastore.KeyFactory;
      import com.google.cloud.datastore.Query;
      import com.google.cloud.datastore.QueryResults;
      import com.google.cloud.datastore.StructuredQuery;
    

アプリが Datastore サービスにアクセスする方法を変更する

Datastore モードの Firestore では、DatastoreService ではなく Datastore クラスを使用します。アプリによる Datastore サービスへのアクセス方法を変更するには:

  1. 次のように、DatastoreServiceFactory.getDatastoreService() メソッドを使用している行を見つけます。

    // Initialize a client
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    
  2. 次のように、DatastoreServiceFactory.getDatastoreService()DatastoreOptions.getDefaultInstance().getService() メソッドに置き換えます。

    // Initialize a client
    Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
    

Datastore で生成されたキーを取得する

クライアントを初期化した後、適切な Kind の新しい KeyFactory を作成してキーを取得し、Datastore でキーを生成します。Datastore で生成された鍵を取得するには:

  1. newKeyFactory を作成します。

  2. setKind() メソッドを呼び出して、クエリの分類に使用するエンティティの kind を確認します。

  3. newKey() メソッドを追加して、Datastore キーを生成します。

    //Prepare a new entity
    String kind = "visit";
    Key key = datastore.allocateId(datastore.newKeyFactory().setKind(kind).newKey());
    

エンティティ作成の変更

Datastore キーを取得したら、次のメソッドを使用してエンティティを作成します。

  1. Entity.newBuilder を使用して、Datastore によって生成されたキーを渡します。

    次のように、Entity コンストラクタ呼び出しを使用している行を見つけます。

    Entity visit = new Entity(kind);
    

    次のように、Entity コンストラクタ呼び出しを Entity.newBuilder コンストラクタ呼び出しに置き換えます。

    Entity visit = Entity.newBuilder(key);
    
  2. エンティティのプロパティを設定するには、set メソッドを使用します。

    第 1 パラメータは目的のプロパティ、第 2 パラメータは値です。timestamp プロパティの場合、値は Instant.toString() ではなく Timestamp です。

    次のように、setProperty メソッドを使用している行を見つけます。

    visit.setProperty("user_ip", userIp);
    visit.setProperty("timestamp", Instant.now().toString());
    

    次のように、setProperty メソッドを set メソッドに置き換えます。

    Entity visit = Entity.newBuilder(key).set("user_ip", userIp).set("timestamp", Timestamp.now()).build();
    

トランザクションを commit する

Datastore モードの Firestore クライアント ライブラリは、add() メソッドを使用してトランザクションを commit します。トランザクションを commit するには:

  1. 次のように、put() メソッドを使用している行を探します。

    // Save the entity
    datastore.put(visit);
    
  2. 次のように、put() メソッドを add() メソッドに置き換えます。

    // Save the entity
    datastore.add(visit);
    

クエリ結果

クエリは、指定された一連の条件を満たす entities を取得します。次の方法で結果を表示できます。

  • OrderBy メソッドは、結果を昇順または降順で表示します。

  • Limit メソッドは、同じビルダーで取得される結果の最大数を制限します。

クエリでは、kind 変数を含むビルダー パターン メソッドを使用します。kind 変数は、Datastore で生成された鍵を取得するステップで Visit に設定されています。

最初の 10 件の結果を取得するには:

  1. 次のように、addSort() メソッドを使用している行を探します。

      // Retrieve the last 10 visits from the datastore, ordered by timestamp.
      Query query = new Query(kind).addSort("timestamp", Query.SortDirection.DESCENDING);
      List<Entity> results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));
    
  2. 次のように、addSort() メソッドを setOrderBy() メソッドに置き換え、setLimit() メソッドを追加します。

    // Retrieve the last 10 visits from the datastore, ordered by timestamp.
    Query<Entity> query = Query.newEntityQueryBuilder()
                            .setKind(kind)
                            .setOrderBy(StructuredQuery.OrderBy.desc("timestamp"))
                            .setLimit(10)
                            .build();
    
  3. クエリの準備ができたら、datastore.run() を使用してコードを実行し、結果を QueryResultsEntity コレクションに収集します。

    結果の QueryResults オブジェクトは、hasNext() 関数を持つイテレータです。

  4. 結果リストをループするのではなく、結果セットに処理対象の next オブジェクトがあるかどうかを確認します。次に例を示します。

    QueryResults<Entity> results = datastore.run(query);
    
          resp.setContentType("text/plain");
          PrintWriter out = resp.getWriter();
          out.print("Last 10 visits:\n");
          while (results.hasNext()) {
              Entity entity = results.next();
              out.format(
                      "Time: %s Addr: %s\n", entity.getTimestamp("timestamp"), entity.getString("user_ip"));
          }
    

Java 8 アプリを Datastore モードの Firestore に移行する方法の例について確認したい場合は、GitHub の App Engine Datastore for Java 8 コードサンプルDatastore モードの Firestore のコードサンプルを比較してください。

次のステップ