文档删除 #
一、删除概述 #
ArangoDB使用REMOVE关键字删除文档,删除操作不可恢复。
1.1 删除方式 #
| 方式 | 说明 |
|---|---|
| REMOVE | AQL删除语法 |
| remove | JavaScript API |
| truncate | 清空整个集合 |
1.2 注意事项 #
text
警告:
├── 删除操作不可恢复
├── 边文档删除不影响顶点
├── 删除会生成新的_rev
└── 建议使用事务保证一致性
二、单条删除 #
2.1 使用_key删除 #
aql
REMOVE "user_001" IN users
2.2 使用_id删除 #
aql
REMOVE "users/user_001" IN users
2.3 使用文档对象删除 #
aql
REMOVE { _key: "user_001" } IN users
2.4 返回被删除的文档 #
aql
REMOVE "user_001" IN users
RETURN OLD
2.5 JavaScript删除 #
javascript
db.users.remove("user_001");
2.6 返回删除结果 #
javascript
var result = db.users.remove("user_001");
print(result);
三、条件删除 #
3.1 按条件删除 #
aql
FOR user IN users
FILTER user.status == "inactive"
REMOVE user IN users
3.2 返回删除的文档 #
aql
FOR user IN users
FILTER user.status == "inactive"
REMOVE user IN users
RETURN OLD
3.3 多条件删除 #
aql
FOR user IN users
FILTER user.status == "deleted"
AND user.deletedAt < DATE_SUBTRACT(DATE_NOW(), 30, "days")
REMOVE user IN users
3.4 范围删除 #
aql
FOR user IN users
FILTER user.age < 18
REMOVE user IN users
3.5 使用子查询删除 #
aql
LET inactiveUsers = (
FOR user IN users
FILTER user.lastLogin < DATE_SUBTRACT(DATE_NOW(), 90, "days")
RETURN user._key
)
FOR key IN inactiveUsers
REMOVE key IN users
四、批量删除 #
4.1 删除多个文档 #
aql
FOR key IN ["user_001", "user_002", "user_003"]
REMOVE key IN users
4.2 批量删除并返回 #
aql
FOR user IN users
FILTER user.status == "expired"
REMOVE user IN users
RETURN OLD._key
4.3 分批删除 #
aql
FOR user IN users
FILTER user.status == "inactive"
LIMIT 1000
REMOVE user IN users
4.4 JavaScript批量删除 #
javascript
var keys = ["user_001", "user_002", "user_003"];
keys.forEach(function(key) {
db.users.remove(key);
});
4.5 使用removeByExample #
javascript
db.users.removeByExample({ status: "inactive" });
五、删除选项 #
5.1 waitForSync #
aql
REMOVE "user_001" IN users
OPTIONS { waitForSync: true }
5.2 ignoreRevs #
忽略版本检查:
aql
REMOVE {
_key: "user_001",
_rev: "_old_rev"
} IN users
OPTIONS { ignoreRevs: true }
5.3 returnOld #
返回被删除的文档:
aql
REMOVE "user_001" IN users
OPTIONS { returnOld: true }
RETURN OLD
5.4 完整选项示例 #
aql
REMOVE "user_001" IN users
OPTIONS {
waitForSync: true,
ignoreRevs: true
}
RETURN OLD
六、清空集合 #
6.1 truncate #
javascript
db.users.truncate();
6.2 AQL方式 #
aql
FOR user IN users
REMOVE user IN users
6.3 区别 #
| 方式 | 速度 | 重置计数器 |
|---|---|---|
| truncate | 快 | 是 |
| AQL循环 | 慢 | 否 |
七、删除边文档 #
7.1 删除单条边 #
aql
REMOVE "follow_001" IN follows
7.2 删除用户的所有边 #
aql
FOR edge IN follows
FILTER edge._from == "users/user_001" OR edge._to == "users/user_001"
REMOVE edge IN follows
7.3 删除特定类型的边 #
aql
FOR edge IN follows
FILTER edge.type == "temporary"
REMOVE edge IN follows
八、级联删除 #
8.1 删除用户及相关数据 #
aql
LET userId = "user_001"
LET userEdges = (
FOR edge IN follows
FILTER edge._from == CONCAT("users/", userId)
OR edge._to == CONCAT("users/", userId)
RETURN edge._key
)
FOR key IN userEdges
REMOVE key IN follows
REMOVE userId IN users
8.2 使用事务级联删除 #
javascript
db._executeTransaction({
collections: { write: ["users", "posts", "comments"] },
action: function() {
var db = require("@arangodb").db;
var userId = "user_001";
db._query(`
FOR comment IN comments
FILTER comment.userId == @userId
REMOVE comment IN comments
`, { userId: userId });
db._query(`
FOR post IN posts
FILTER post.authorId == @userId
REMOVE post IN posts
`, { userId: userId });
db.users.remove(userId);
}
});
8.3 删除顶点及所有边 #
aql
LET vertexId = "users/user_001"
FOR v, e IN ANY vertexId GRAPH "social"
REMOVE e IN follows
REMOVE vertexId IN users
九、软删除 #
9.1 实现软删除 #
aql
UPDATE "user_001" WITH {
deleted: true,
deletedAt: DATE_NOW()
} IN users
9.2 查询时过滤 #
aql
FOR user IN users
FILTER user.deleted != true
RETURN user
9.3 恢复软删除 #
aql
UPDATE "user_001" WITH {
deleted: false,
deletedAt: null
} IN users
9.4 永久删除软删除数据 #
aql
FOR user IN users
FILTER user.deleted == true
AND user.deletedAt < DATE_SUBTRACT(DATE_NOW(), 30, "days")
REMOVE user IN users
十、JavaScript API #
10.1 remove #
javascript
db.users.remove("user_001");
10.2 removeByExample #
javascript
db.users.removeByExample({ status: "inactive" });
10.3 removeByKeys #
javascript
db.users.removeByKeys(["user_001", "user_002", "user_003"]);
10.4 truncate #
javascript
db.users.truncate();
10.5 删除并检查 #
javascript
if (db.users.exists("user_001")) {
db.users.remove("user_001");
print("删除成功");
} else {
print("文档不存在");
}
十一、实战示例 #
11.1 删除过期会话 #
aql
FOR session IN sessions
FILTER session.expiresAt < DATE_NOW()
REMOVE session IN sessions
11.2 清理测试数据 #
aql
FOR user IN users
FILTER user.email LIKE "%@test.com"
REMOVE user IN users
11.3 删除重复文档 #
aql
FOR user IN users
COLLECT email = user.email WITH COUNT INTO count
FILTER count > 1
LET duplicates = (
FOR u IN users
FILTER u.email == email
SORT u.createdAt ASC
LIMIT 1, count - 1
RETURN u._key
)
FOR key IN duplicates
REMOVE key IN users
11.4 删除孤立边 #
aql
FOR edge IN follows
LET fromExists = DOCUMENT(edge._from)
LET toExists = DOCUMENT(edge._to)
FILTER fromExists == null OR toExists == null
REMOVE edge IN follows
11.5 批量删除大量数据 #
javascript
function batchRemove(collection, batchSize) {
var removed = 0;
while (true) {
var result = db._query(`
FOR doc IN @@collection
LIMIT @batchSize
REMOVE doc IN @@collection
RETURN 1
`, {
"@collection": collection,
batchSize: batchSize
});
var count = result.toArray().length;
removed += count;
if (count < batchSize) break;
}
return removed;
}
var total = batchRemove("logs", 1000);
print("共删除 " + total + " 条记录");
十二、性能优化 #
12.1 使用索引 #
确保删除条件字段有索引:
javascript
db.users.ensureHashIndex(["status"]);
12.2 分批删除 #
aql
FOR user IN users
FILTER user.status == "inactive"
LIMIT 1000
REMOVE user IN users
12.3 使用truncate #
清空整个集合时使用truncate:
javascript
db.users.truncate();
十三、错误处理 #
13.1 文档不存在 #
aql
REMOVE "nonexistent_key" IN users
OPTIONS { ignoreErrors: true }
13.2 JavaScript错误处理 #
javascript
try {
db.users.remove("user_001");
} catch (e) {
if (e.errorNum === 1202) {
print("文档不存在");
} else if (e.errorNum === 1200) {
print("版本冲突");
}
}
13.3 事务回滚 #
javascript
try {
db._executeTransaction({
collections: { write: ["users", "orders"] },
action: function() {
var db = require("@arangodb").db;
db.users.remove("user_001");
throw new Error("模拟错误");
}
});
} catch (e) {
print("事务已回滚: " + e.message);
}
十四、总结 #
文档删除要点:
- REMOVE:AQL删除语法
- 条件删除:结合FILTER使用
- 批量删除:使用FOR循环
- 级联删除:使用事务保证一致性
- 软删除:标记删除而非真正删除
下一步,让我们学习基础查询!
最后更新:2026-03-27