Pipeline オペレーションを使用してデータを変更する
update(...) ステージと delete(...) ステージのデータ操作言語(DML)を使用して、ドキュメントをクエリしてからデータを削除または変更できるデータ パイプラインを構築します。
エディションの要件
このページで説明するオペレーションには、Firestore Enterprise エディションが必要です。
始める前に
Pipeline オペレーションを使用してデータベースをクエリする方法を理解している必要があります。
ドキュメントを更新する
update(...) DML ステージを使用して、ドキュメントをクエリし、データを追加または変更できるデータ パイプラインを構築します。
すべての DML ステージは、パイプラインの最後に配置する必要があります。このステージに移行するドキュメントには、更新するドキュメントを特定するための __name__ フィールドを含める必要があります。更新しようとしたドキュメントが存在しない場合、オペレーションは失敗します。
たとえば、次のオペレーションは、データモデルの変更をコレクション グループ内のすべてのドキュメントにバックフィルします。パイプラインは、users コレクション グループ内のすべてのドキュメントのうち、そのフィールドがないドキュメントすべてに preferences.color フィールドを追加します。
Node.js
const snapshot = await db.pipeline() .collectionGroup("users") .where(not(exists(field("preferences.color")))) .addFields(constant(null).as("preferences.color")) .removeFields("color") .update() .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Constant, Field, Not snapshot = ( client.pipeline() .collection_group("users") .where(Not(Field.of("preferences.color").exists())) .add_fields(Constant.of(None).as_("preferences.color")) .remove_fields("color") .update() .execute() )
Java
Pipeline.Snapshot snapshot = firestore.pipeline() .collectionGroup("users") .where(not(exists(field("preferences.color")))) .addFields(constant((String) null).as("preferences.color")) .removeFields("color") .update() .execute().get();
ドキュメントを削除する
delete(...) ステージ DML ステージを使用して、ドキュメントをクエリしてデータを削除できるデータ パイプラインを構築します。一括削除の誤りを防ぐため、delete(...) で終わるパイプラインには、少なくとも 1 つの where(...) ステージを含める必要があります。すべての DML ステージはパイプラインの最後に配置する必要があります。
たとえば、次のパイプラインは、address.users が USA に設定され、__create_time__ が 10 日未満のすべての users ドキュメントを削除します。
Node.js
const pipeline = db.pipeline() .collectionGroup("users") .where(field("address.country").equal("USA")) .where(field("__create_time__").timestampAdd("day", 10).lessThan(currentTimestamp())) .delete(); await pipeline.execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import CurrentTimestamp, Field snapshot = ( client.pipeline() .collection_group("users") .where(Field.of("address.country").equal("USA")) .where( Field.of("__create_time__") .timestamp_add("day", 10) .less_than(CurrentTimestamp()) ) .delete() .execute() )
Java
Pipeline.Snapshot deleteResults = firestore.pipeline() .collectionGroup("users") .where(field("address.country").equal("USA")) .where(field("__create_time__").add(constant(10)).lessThan(currentTimestamp())) .delete() .execute().get();
整合性
update(...) ステージと delete() ステージを含むパイプライン オペレーションは、トランザクション内ではサポートされていません。DML ステージは、次の動作でトランザクションの外部で実行されます。
- 各ドキュメントは個別に更新されます。つまり、オペレーションはドキュメント間でアトミックではありません。操作は最初のエラーで失敗し、部分的な成功は可能です。
- 次のステージがサポートされています。
collection(...)collection_group(...)where(...)select(...)add_fields(...)remove_fields(...)let(...)sort(...)limit(...)offset(...)
- 次のステージはサポートされていません。
aggregate(...)distinct(...)unnest(...)find_nearest(...)union(...)、結合、サブクエリなどのマルチクエリ ステージは、DML ステージの前に使用できません。
制限事項
DML ステージには次の制限事項があります。
- DML ステージは、
.execute()を呼び出す前のパイプライン定義の最後のステージである必要があります。 update(...)ステージとdelete()ステージを含むパイプライン オペレーションは、トランザクション内ではサポートされていません。- DML ステージの前のステージで同じ
__name__を持つ複数のドキュメントが生成された場合、各インスタンスが処理されます。update(...)の場合、同じターゲット ドキュメントが複数回変更される可能性があります。delete(...)の場合、最初の試行後の後続の試行は no-op になります。