使用 update(...) 和 delete(...) 数据操纵语言 (DML) 阶段构建可查询文档然后删除或修改数据的数据流水线。
版本要求
本页介绍的操作需要 Firestore 企业版。
准备工作
您应该熟悉如何使用流水线操作查询数据库。
更新文档
使用 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();
Go
snapshot := client.Pipeline(). CollectionGroup("users"). Where(firestore.Not(firestore.FieldExists(firestore.FieldOf("preferences.color")))). AddFields(firestore.Selectables( firestore.ConstantOfNull().As("preferences.color"), )). RemoveFields(firestore.Fields("color")). Update(). Execute(ctx)
删除文档
使用 delete(...) 阶段 DML 阶段构建可查询文档然后删除数据的数据流水线。为防止意外批量删除,以 delete(...) 结尾的流水线应至少包含一个 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();
Go
snapshot := client.Pipeline(). CollectionGroup("users"). Where(firestore.FieldOf("address.country").Equal("USA")). Where(firestore.FieldOf("__create_time__").Add(firestore.ConstantOf(10)).LessThan(firestore.CurrentTimestamp())). Delete(). Execute(ctx)
一致性
事务中不支持包含 update(...) 和 delete() 阶段的流水线操作。DML 阶段在事务之外运行,具有以下行为:
- 每个文档都是独立更新的。这意味着,跨文档的操作不具有原子性。 操作在出现第一个错误时失败,并且可能部分成功。
- 支持以下阶段:
collection(...)collection_group(...)where(...)select(...)add_fields(...)remove_fields(...)let(...)sort(...)limit(...)offset(...)
- 不支持以下阶段:
aggregate(...)distinct(...)unnest(...)find_nearest(...)- 在 DML 阶段之前,不允许使用多查询阶段(例如
union(...)、联接和子查询)。
限制
请注意 DML 阶段的以下限制:
- 在调用
.execute()之前,DML 阶段必须是流水线定义中的最后阶段。 - 事务中不支持具有
update(...)和delete()阶段的流水线操作。 - 如果 DML 阶段之前的阶段生成了多个具有相同
__name__的文档,则每个实例都会被处理。对于update(...),这意味着同一目标文档可能会被修改多次。对于delete(...),首次尝试之后的后续尝试将不执行任何操作。