使用流水线操作修改数据
使用 update(...) 和 delete(...) 数据操纵语言 (DML) 阶段来构建数据流水线,这些流水线可以查询文档,然后删除或修改数据。
版本要求
本页介绍的操作需要 Firestore 企业版。
准备工作
您应该熟悉如何 使用流水线操作查询数据库。
更新文档
使用 update(...) DML 阶段来构建数据流水线
,这些流水线可以查询文档,然后添加或修改数据。
所有 DML 阶段都必须位于流水线的末尾。
进入此阶段的文档必须包含 __name__ 字段,以标识要更新的文档。如果您尝试更新的任何文档不存在,该操作将失败。
例如,以下操作会将数据模型更改回填到合集组中的所有文档。流水线会将 preferences.color 字段添加到 users 合集组中缺少该字段的所有文档。
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(...) 结尾的流水线应至少包含一个 where(...) 阶段。
所有 DML 阶段都必须位于流水线的末尾。
例如,以下流水线会删除所有 users 文档,这些文档的
address.users 设置为 USA,且 __create_time__ 小于 10 天:
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(...)- DML 阶段之前不允许使用多查询阶段,例如
union(...)、联接和子查询。
限制
请注意 DML 阶段的以下限制:
- DML 阶段必须是调用
.execute()之前的流水线定义中的最后一个阶段。 - 事务中不支持使用
update(...)和delete()阶段的流水线操作。 - 如果 DML 阶段之前的阶段生成了多个具有相同
__name__的文档,则系统会处理每个实例。对于update(...),这意味着同一个目标文档可能会被多次修改。对于delete(...),第一次尝试后的后续尝试将是空操作。