WorkflowsでFirestore用コネクタを用いてFirestoreから複数のドキュメントを一括で取得する

WorkflowsでFirestore用コネクタを用いてFirestoreから複数のドキュメントを一括で取得する

WorkflowsからFiresotre用コネクタを用いてFirestore上の複数ドキュメントを取得する方法について調べてみました。
Clock Icon2024.11.03

概要

WorkflowsでFirestore用コネクタを用いるとFirestore上のドキュメントを書き込んだり、取得したりすることができます。
以前のブログではドキュメントの取得を1件ずつ行う方法を検証しましたが、Firestore用コネクタには複数のドキュメントを一括で取得するAPI(以下)も提供されています。
https://cloud.google.com/workflows/docs/reference/googleapis/firestore/v1/projects.databases.documents/batchGet

今回はこのAPIを用いてFirestore上の複数のドキュメントを一括で取得する方法をまとめてみました。

やってみる

まずはリファレンスからAPIの叩き方を知る

まずはリファレンスを確認します。
複数のドキュメントを一括取得するAPIは下記のAPI(以下batchGet)となっております。

Method: googleapis.firestore.v1.projects.databases.documents.batchGet 

https://cloud.google.com/workflows/docs/reference/googleapis/firestore/v1/projects.databases.documents/batchGet

リファレンスより呼び出しのパラメータには以下を指定することがわかります。

パラメータ 概要
database 必須。projects/プロジェクトID/databases/データベースIDの形式で指定する
body 必須。BatchGetDocumentsRequestオブジェクト

bodyBatchGetDocumentRequestオブジェクトの形式で取得したドキュメントの条件を指定します。

https://cloud.google.com/workflows/docs/reference/googleapis/firestore/v1/Overview#batchgetdocumentsrequest

指定できる条件はいくつかありますが以下に代表的なものを取り上げました。

フィールド名 概要
documents 配列で指定。projects/プロジェクトID/databases/データベースID/documents/ドキュメントのパスの形式で指定。ドキュメントのいずれかが指定されたデータベースの子リソースでない場合、リクエストは失敗します。重複した名前は消去されます。
mask 取得フィールドの制限に使用
newTransaction 新しいトランザクションを開始し、ドキュメントを読み込む。デフォルトは読み取り専用トランザクション

上記のうちdocumentsを指定することで複数のドキュメントを一括で取得することができます。

実行してみる

検証用のワークフローは以下となります。

- initialize:
    assign:
      - project: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
      - collection: "コレクション名"
      - database_id: "データベースID"
      - document_id_1: "batchget_test_1"
      - document_id_2: "batchget_test_2"
      - document_id_3: "batchget_test_3"
      - path1: ${"projects/" + project + "/databases/" + database_id + "/documents/" + collection + "/" + document_id_1}
      - path2: ${"projects/" + project + "/databases/" + database_id + "/documents/" + collection + "/" + document_id_2}
      - path3: ${"projects/" + project + "/databases/" + database_id + "/documents/" + collection + "/" + document_id_3}

- read_items:
    call: googleapis.firestore.v1.projects.databases.documents.batchGet
    args:
      database: ${"projects/" + project + "/databases/" + database_id}
      body:
          documents: ${[path1, path2]}
    result: read_result
- logStep:
      call: sys.log
      args:
          text: ${read_result}

簡単に解説します。

ステップ1: initialize
変数を初期化および割り当てを行っています。

変数 内容
project 環境変数 GOOGLE_CLOUD_PROJECT_ID からプロジェクトIDを取得します。
collection Firestoreコレクションの名前を "config_collection" として設定します。
database_id FirestoreのデフォルトデータベースIDを "(default)" として設定します。
document_id_x 一括取得対象の定義。document_id_(1,2,3)に対して取得したいドキュメントのIDをそれぞれ "batchget_test_x"として設定します。
pathx projects/プロジェクトID/databases/データベースID/documents/ドキュメントのパスの形式で指定

ステップ2: read_items
read_itemsステップでは、一括でドキュメントを取得する処理を行っています。

処理 概要
call 使用するAPIは googleapis.firestore.v1.projects.databases.documents.batchGetです。
args APIコールに必要な引数を設定します。
database Firestoreデータベースのパスをprojects/プロジェクトID/databases/データベースID形式で指定します。
documents 取得したいドキュメントのパスをリストで指定します
result APIコールの結果を read_result という変数に格納します。

ステップ3: logStep
logStepステップでは、取得した結果をログに出力します。


今回は取得対象としてdocument_id_1document_id_2document_id_3という3つのドキュメントIDを指定しています。
Firestoreに存在するのはdocument_id_1document_id_3のみとなっており、一括取得対象が存在していた場合と存在しなかった場合のレスポンスを観測できます。

ドキュメント名 状態
document_id_1 存在する
document_id_2 存在しない
document_id_3 存在する

Firestoreに作成してあるドキュメントの内容は以下です。test_fieldという一つのフィールドを持つだけのシンプルな構造です。

設定値
ドキュメント名 batchget_test_1
test_field hello batch get
ドキュメント名 batchget_test_3
test_field batchget_test3

それではワークフローを実行してログ(read_result)を見てみます。出力されたログ(textPayload)は以下です。

[
  {
    "found": {
      "createTime": "2024-11-02T15:27:31.980941Z",
      "fields": {
        "test_field": {
          "stringValue": "hello batch get"
        }
      },
      "name": "projects/プロジェクトID/databases/データベースID/documents/コレクション名/batchget_test_1",
      "updateTime": "2024-11-02T15:27:31.980941Z"
    },
    "readTime": "2024-11-02T15:46:20.278390Z"
  },
  {
    "found": {
      "createTime": "2024-11-02T15:46:20.278390Z",
      "fields": {
        "test_field": {
          "stringValue": "batchget_test3"
        }
      },
      "name": "projects/プロジェクトID/databases/データベースID/documents/コレクション名/batchget_test_3",
      "updateTime": "2024-11-02T15:46:20.278390Z"
    },
    "readTime": "2024-11-02T15:46:20.278390Z"
  },
  {
    "missing": "projects/プロジェクトID/databases/データベースID/documents/コレクション名/batchget_test_2",
    "readTime": "2024-11-02T15:46:20.278390Z"
  }
]

ドキュメントが存在していた場合foundとして、フィールド内容などが出力されている様子がわかります。一方で、ドキュメントが存在していなかった場合はmissingと出力されています。
今更ですがレスポンスのリファレンスも確認します。
https://cloud.google.com/workflows/docs/reference/googleapis/firestore/v1/Overview#batchgetdocumentsresponse

レスポンスのフィールドの概要としては以下となります。

フィールド名 概要
found 取得対象ドキュメント
missing 取得しようとしたが存在しなかったドキュメント
readTime ドキュメントが読み込まれた時刻

Firestore上に存在するドキュメントはbatchget_test_1batchget_test_3でありどちらもfoundとなっているので確かに取得できていました。
batchGet、いいですね。気に入っちゃいました。特に叩き方も難しい点はないAPIですね。

まとめ

  • WorkflowsからFirestore上の複数ドキュメントの一括取得にはbatchGetAPIを用いることができる
  • 取得対象が存在した場合はfoundキーと共にドキュメントの詳細を取得される
  • 取得対象が存在しなかった場合はmissingキーとドキュメントパスが出力される

ワークフローでは複数ドキュメントを扱って情報取得する場合も多いと思いますので押さえておきたいAPIだなと思いました。
パスの指定などでprojects/プロジェクトID/databases/データベースIDというように指定された形式にする必要があるので、APIのリファレンスを見てどういった形式なのかをしっかり確認しながら実装した方がよいと思いました(他のサービスのAPIでも同様ですが)。

それではまた。ナマステー

参考

Cloud Firestore API Connector Overview

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.