删除文档 #
一、Delete概述 #
1.1 基本语法 #
javascript
Delete(ref)
1.2 Delete特点 #
text
Delete特点:
├── 立即删除文档
├── 返回被删除的文档
├── 不可恢复(除非有备份)
├── 历史记录保留(根据history_days)
└── 需要适当权限
二、基本删除 #
2.1 通过Ref删除 #
javascript
// 删除单个文档
Delete(Ref(Collection("users"), "123456"))
// 返回被删除的文档
{
ref: Ref(Collection("users"), "123456"),
ts: 1704067200000000,
data: {
name: "Tom",
email: "tom@example.com"
}
}
2.2 通过索引删除 #
javascript
// 通过索引查找后删除
Let(
{
doc: Get(Match(Index("users_by_email"), "tom@example.com"))
},
Delete(Select(["ref"], Var("doc")))
)
2.3 删除返回值 #
javascript
// Delete返回被删除的文档
Let(
{
deleted: Delete(Ref(Collection("users"), "123456"))
},
{
message: "User deleted",
deletedId: Select(["ref", "id"], Var("deleted")),
deletedName: Select(["data", "name"], Var("deleted"))
}
)
三、条件删除 #
3.1 检查存在后删除 #
javascript
// 检查文档存在后删除
Let(
{
ref: Ref(Collection("users"), "123456")
},
If(
Exists(Var("ref")),
Delete(Var("ref")),
{ message: "Document not found" }
)
)
3.2 状态验证删除 #
javascript
// 验证状态后删除
Let(
{
ref: Ref(Collection("orders"), "order_001"),
doc: Get(Var("ref")),
status: Select(["data", "status"], Var("doc"))
},
If(
Or(
Equals(Var("status"), "cancelled"),
Equals(Var("status"), "completed")
),
Delete(Var("ref")),
Abort("Cannot delete order in current status")
)
)
3.3 权限验证删除 #
javascript
// 验证所有者后删除
Let(
{
ref: Ref(Collection("posts"), "post_001"),
doc: Get(Var("ref")),
owner: Select(["data", "authorId"], Var("doc")),
currentUser: CurrentIdentity()
},
If(
Equals(Var("owner"), Var("currentUser")),
Delete(Var("ref")),
Abort("You don't have permission to delete this post")
)
)
四、批量删除 #
4.1 Map批量删除 #
javascript
// 批量删除多个文档
Map(
[
Ref(Collection("users"), "1"),
Ref(Collection("users"), "2"),
Ref(Collection("users"), "3")
],
Lambda("ref", Delete(Var("ref")))
)
4.2 Foreach批量删除 #
javascript
// 使用Foreach批量删除
Foreach(
Paginate(Match(Index("users_by_status"), "deleted")),
Lambda("ref", Delete(Var("ref")))
)
4.3 条件批量删除 #
javascript
// 条件批量删除
Foreach(
Filter(
Paginate(Documents(Collection("logs"))),
Lambda("ref",
Let(
{ doc: Get(Var("ref")) },
LT(
Select(["data", "createdAt"], Var("doc")),
TimeSubtract(Now(), 30, "day")
)
)
)
),
Lambda("ref", Delete(Var("ref")))
)
4.4 分页批量删除 #
javascript
// 分页批量删除(处理大量数据)
Let(
{
deleteBatch: Query(
Lambda("cursor",
Let(
{
page: If(
Equals(Var("cursor"), null),
Paginate(Match(Index("old_logs")), { size: 100 }),
Paginate(Match(Index("old_logs")), {
size: 100,
after: Var("cursor")
})
)
},
Do(
Foreach(
Select(["data"], Var("page")),
Lambda("ref", Delete(Var("ref")))
),
If(
ContainsPath(Var("page"), ["after"]),
Select(["after"], Var("page")),
false
)
)
)
)
)
},
Var("deleteBatch")
)
五、级联删除 #
5.1 手动级联删除 #
javascript
// 删除用户及其相关数据
Let(
{
userRef: Ref(Collection("users"), "user_001")
},
Do(
// 删除用户的订单
Foreach(
Paginate(Match(Index("orders_by_user"), Var("userRef"))),
Lambda("orderRef", Delete(Var("orderRef")))
),
// 删除用户的评论
Foreach(
Paginate(Match(Index("comments_by_user"), Var("userRef"))),
Lambda("commentRef", Delete(Var("commentRef")))
),
// 删除用户
Delete(Var("userRef"))
)
)
5.2 复杂级联删除 #
javascript
// 删除订单及其订单项
Let(
{
orderRef: Ref(Collection("orders"), "order_001")
},
Do(
// 删除订单项
Foreach(
Paginate(Match(Index("order_items_by_order"), Var("orderRef"))),
Lambda("itemRef", Delete(Var("itemRef")))
),
// 删除支付记录
Foreach(
Paginate(Match(Index("payments_by_order"), Var("orderRef"))),
Lambda("paymentRef", Delete(Var("paymentRef")))
),
// 删除订单历史
Foreach(
Paginate(Match(Index("order_history_by_order"), Var("orderRef"))),
Lambda("historyRef", Delete(Var("historyRef")))
),
// 删除订单
Delete(Var("orderRef"))
)
)
5.3 使用函数封装级联删除 #
javascript
// 创建级联删除函数
CreateFunction({
name: "delete_user_cascade",
role: Role("admin"),
body: Query(
Lambda("userRef",
Do(
// 删除所有关联数据
Foreach(
Paginate(Match(Index("orders_by_user"), Var("userRef"))),
Lambda("ref", Delete(Var("ref")))
),
Foreach(
Paginate(Match(Index("posts_by_author"), Var("userRef"))),
Lambda("ref", Delete(Var("ref")))
),
Foreach(
Paginate(Match(Index("comments_by_user"), Var("userRef"))),
Lambda("ref", Delete(Var("ref")))
),
// 最后删除用户
Delete(Var("userRef"))
)
)
)
})
// 使用函数
Call(Function("delete_user_cascade"), Ref(Collection("users"), "user_001"))
六、软删除 #
6.1 软删除实现 #
javascript
// 软删除:标记为已删除
Update(Ref(Collection("users"), "user_001"), {
data: {
deleted: true,
deletedAt: Now()
}
})
// 查询时过滤已删除
Filter(
Paginate(Documents(Collection("users"))),
Lambda("ref",
Not(Select(["data", "deleted"], Get(Var("ref")), false))
)
)
6.2 软删除索引 #
javascript
// 创建软删除索引
CreateIndex({
name: "active_users",
source: {
collection: Collection("users"),
fields: {
notDeleted: Query(
Lambda("doc",
Not(Select(["data", "deleted"], Var("doc"), false))
)
)
}
},
terms: [
{ binding: "notDeleted" }
]
})
// 查询活跃用户
Paginate(Match(Index("active_users"), true))
6.3 恢复软删除 #
javascript
// 恢复软删除的文档
Update(Ref(Collection("users"), "user_001"), {
data: {
deleted: false,
deletedAt: null,
restoredAt: Now()
}
})
七、删除前备份 #
7.1 删除前复制 #
javascript
// 删除前复制到归档集合
Let(
{
ref: Ref(Collection("users"), "user_001"),
doc: Get(Var("ref"))
},
Do(
// 复制到归档
Create(Collection("users_archive"), {
data: Merge(
Select(["data"], Var("doc")),
{
originalId: Select(["ref", "id"], Var("doc")),
archivedAt: Now()
}
)
}),
// 删除原文档
Delete(Var("ref"))
)
)
7.2 批量归档删除 #
javascript
// 批量归档后删除
Foreach(
Paginate(Match(Index("users_to_archive"))),
Lambda("ref",
Let(
{ doc: Get(Var("ref")) },
Do(
Create(Collection("users_archive"), {
data: Merge(
Select(["data"], Var("doc")),
{
originalId: Select(["ref", "id"], Var("doc")),
archivedAt: Now()
}
)
}),
Delete(Var("ref"))
)
)
)
)
八、删除验证 #
8.1 引用检查 #
javascript
// 检查是否有引用
Let(
{
productRef: Ref(Collection("products"), "prod_001"),
orders: Match(Index("orders_by_product"), Var("productRef"))
},
If(
Equals(Count(Var("orders")), 0),
Delete(Var("productRef")),
Abort("Cannot delete: product has orders")
)
)
8.2 业务规则验证 #
javascript
// 复杂业务规则验证
Let(
{
orderRef: Ref(Collection("orders"), "order_001"),
doc: Get(Var("orderRef"))
},
If(
And(
// 订单已完成或已取消
Or(
Equals(Select(["data", "status"], Var("doc")), "completed"),
Equals(Select(["data", "status"], Var("doc")), "cancelled")
),
// 订单创建超过30天
GT(
TimeDiff(Select(["data", "createdAt"], Var("doc")), Now(), "day"),
30
)
),
Delete(Var("orderRef")),
Abort("Cannot delete order: must be completed/cancelled and older than 30 days")
)
)
九、实际应用示例 #
9.1 删除用户 #
javascript
// 完整的用户删除流程
Let(
{
userRef: Ref(Collection("users"), "user_001"),
currentUser: CurrentIdentity()
},
If(
Equals(Var("userRef"), Var("currentUser")),
Abort("Cannot delete your own account"),
Let(
{ doc: Get(Var("userRef")) },
Do(
// 归档用户数据
Create(Collection("deleted_users"), {
data: {
originalId: Select(["ref", "id"], Var("doc")),
email: Select(["data", "email"], Var("doc")),
name: Select(["data", "name"], Var("doc")),
deletedAt: Now(),
deletedBy: Var("currentUser")
}
}),
// 删除用户凭证
Foreach(
Paginate(Match(Index("credentials_by_user"), Var("userRef"))),
Lambda("ref", Delete(Var("ref")))
),
// 删除用户会话
Foreach(
Paginate(Match(Index("sessions_by_user"), Var("userRef"))),
Lambda("ref", Delete(Var("ref")))
),
// 删除用户
Delete(Var("userRef"))
)
)
)
)
9.2 清理过期数据 #
javascript
// 清理过期的会话数据
Let(
{
cutoffTime: TimeSubtract(Now(), 7, "day")
},
Foreach(
Filter(
Paginate(Documents(Collection("sessions")), { size: 1000 }),
Lambda("ref",
LT(
Select(["data", "createdAt"], Get(Var("ref"))),
Var("cutoffTime")
)
)
),
Lambda("ref", Delete(Var("ref")))
)
)
9.3 批量删除产品 #
javascript
// 批量删除无库存产品
Let(
{
products: Filter(
Paginate(Documents(Collection("products")), { size: 500 }),
Lambda("ref",
Let(
{ doc: Get(Var("ref")) },
And(
Equals(Select(["data", "stock"], Var("doc"), 0), 0),
Equals(Select(["data", "discontinued"], Var("doc"), false), true)
)
)
)
)
},
Foreach(
Var("products"),
Lambda("ref",
Do(
// 归档产品
Let(
{ doc: Get(Var("ref")) },
Create(Collection("products_archive"), {
data: Merge(
Select(["data"], Var("doc")),
{
originalId: Select(["ref", "id"], Var("doc")),
archivedAt: Now()
}
)
})
),
// 删除产品
Delete(Var("ref"))
)
)
)
)
十、删除最佳实践 #
10.1 始终验证 #
javascript
// 好的做法:验证后删除
Let(
{ ref: Ref(Collection("users"), "123456") },
If(
And(
Exists(Var("ref")),
HasPermission(Var("ref"), "delete")
),
Delete(Var("ref")),
Abort("Cannot delete document")
)
)
10.2 记录删除操作 #
javascript
// 记录删除日志
Let(
{
ref: Ref(Collection("users"), "user_001"),
doc: Get(Var("ref"))
},
Do(
// 创建删除日志
Create(Collection("audit_logs"), {
data: {
action: "delete",
collection: "users",
documentId: Select(["ref", "id"], Var("doc")),
data: Select(["data"], Var("doc")),
deletedBy: CurrentIdentity(),
deletedAt: Now()
}
}),
// 删除文档
Delete(Var("ref"))
)
)
10.3 使用事务 #
javascript
// 使用事务确保原子性
Do(
// 删除相关数据
Foreach(
Paginate(Match(Index("items_by_parent"), parentRef)),
Lambda("ref", Delete(Var("ref")))
),
// 删除主文档
Delete(parentRef)
)
十一、总结 #
删除文档要点:
| 操作 | 说明 |
|---|---|
| Delete | 删除文档 |
| Exists | 检查存在 |
| Foreach | 批量删除 |
| Do | 原子操作 |
| 软删除 | 标记删除 |
下一步,让我们学习基础查询!
最后更新:2026-03-27