文档插入 #
一、插入概述 #
文档是ArangoDB中数据存储的基本单位,以JSON格式存储在集合中。
1.1 文档结构 #
json
{
"_key": "user_001",
"_id": "users/user_001",
"_rev": "_abc123",
"name": "张三",
"email": "zhangsan@example.com",
"age": 28
}
1.2 系统属性 #
| 属性 | 说明 | 自动生成 |
|---|---|---|
| _key | 文档唯一标识 | 是(可手动指定) |
| _id | 全局标识(集合名/_key) | 是 |
| _rev | 版本号 | 是 |
二、单条插入 #
2.1 AQL插入 #
aql
INSERT {
name: "张三",
email: "zhangsan@example.com",
age: 28
} INTO users
2.2 指定_key #
aql
INSERT {
_key: "user_001",
name: "张三",
email: "zhangsan@example.com",
age: 28
} INTO users
2.3 JavaScript插入 #
javascript
db.users.insert({
name: "张三",
email: "zhangsan@example.com",
age: 28
});
2.4 返回插入的文档 #
aql
INSERT {
name: "张三",
email: "zhangsan@example.com"
} INTO users
RETURN NEW
输出:
json
{
"_key": "12345",
"_id": "users/12345",
"_rev": "_abc123",
"name": "张三",
"email": "zhangsan@example.com"
}
2.5 返回特定字段 #
aql
INSERT {
name: "张三",
email: "zhangsan@example.com"
} INTO users
RETURN NEW._id
三、批量插入 #
3.1 使用FOR循环 #
aql
FOR user IN [
{ name: "张三", email: "zhangsan@example.com" },
{ name: "李四", email: "lisi@example.com" },
{ name: "王五", email: "wangwu@example.com" }
]
INSERT user INTO users
3.2 返回所有插入的文档 #
aql
FOR user IN [
{ name: "张三", email: "zhangsan@example.com" },
{ name: "李四", email: "lisi@example.com" }
]
INSERT user INTO users
RETURN NEW
3.3 JavaScript批量插入 #
javascript
db.users.insert([
{ name: "张三", email: "zhangsan@example.com" },
{ name: "李四", email: "lisi@example.com" },
{ name: "王五", email: "wangwu@example.com" }
]);
3.4 从另一个集合复制 #
aql
FOR doc IN source_collection
INSERT doc INTO target_collection
3.5 批量插入并转换 #
aql
FOR i IN 1..100
INSERT {
_key: CONCAT("user_", i),
name: CONCAT("用户", i),
score: RAND() * 100
} INTO users
四、UPSERT操作 #
4.1 基本UPSERT #
如果存在则更新,不存在则插入:
aql
UPSERT { email: "zhangsan@example.com" }
INSERT {
name: "张三",
email: "zhangsan@example.com",
createdAt: DATE_NOW()
}
UPDATE {
name: "张三",
updatedAt: DATE_NOW()
} IN users
4.2 返回操作结果 #
aql
UPSERT { email: "zhangsan@example.com" }
INSERT { name: "张三", email: "zhangsan@example.com" }
UPDATE { name: "张三" } IN users
RETURN { doc: NEW, type: OLD ? "update" : "insert" }
4.3 UPSERT选项 #
aql
UPSERT { email: "zhangsan@example.com" }
INSERT { name: "张三", email: "zhangsan@example.com" }
UPDATE { name: "张三" } IN users
OPTIONS { ignoreErrors: true }
五、插入选项 #
5.1 waitForSync #
等待数据写入磁盘:
aql
INSERT {
name: "张三",
email: "zhangsan@example.com"
} INTO users
OPTIONS { waitForSync: true }
5.2 overwrite #
覆盖已存在的文档:
aql
INSERT {
_key: "user_001",
name: "张三",
email: "zhangsan@example.com"
} INTO users
OPTIONS { overwrite: true }
5.3 overwriteMode #
覆盖模式:
aql
INSERT {
_key: "user_001",
name: "张三"
} INTO users
OPTIONS { overwriteMode: "replace" }
| 模式 | 说明 |
|---|---|
| replace | 完全替换 |
| update | 合并更新 |
| ignore | 忽略已存在的 |
5.4 returnNew #
返回新文档:
aql
INSERT {
name: "张三"
} INTO users
OPTIONS { returnNew: true }
RETURN NEW
六、插入边文档 #
6.1 创建边文档 #
aql
INSERT {
_from: "users/user_001",
_to: "users/user_002",
type: "follows",
createdAt: DATE_NOW()
} INTO follows
6.2 批量创建边 #
aql
FOR i IN 1..10
INSERT {
_from: CONCAT("users/user_", i),
_to: CONCAT("users/user_", i + 1),
createdAt: DATE_NOW()
} INTO follows
6.3 基于查询创建边 #
aql
FOR user IN users
FILTER user.city == "北京"
FOR other IN users
FILTER other.city == "北京" AND other._key != user._key
INSERT {
_from: user._id,
_to: other._id,
type: "same_city"
} INTO relations
七、使用变量插入 #
7.1 使用LET定义变量 #
aql
LET name = "张三"
LET email = "zhangsan@example.com"
INSERT {
name: name,
email: email
} INTO users
7.2 使用绑定参数 #
aql
INSERT @doc INTO users
JavaScript调用:
javascript
db._query(
"INSERT @doc INTO users RETURN NEW",
{ doc: { name: "张三", email: "zhangsan@example.com" } }
);
7.3 批量参数插入 #
aql
FOR doc IN @docs
INSERT doc INTO users
JavaScript调用:
javascript
db._query(
"FOR doc IN @docs INSERT doc INTO users RETURN NEW",
{
docs: [
{ name: "张三", email: "zhangsan@example.com" },
{ name: "李四", email: "lisi@example.com" }
]
}
);
八、插入验证 #
8.1 使用Schema验证 #
创建带Schema的集合:
javascript
db._create("users", {
schema: {
rule: {
type: "object",
properties: {
name: { type: "string" },
email: { type: "string", format: "email" },
age: { type: "number", minimum: 0 }
},
required: ["name", "email"]
}
}
});
插入有效文档:
aql
INSERT {
name: "张三",
email: "zhangsan@example.com",
age: 28
} INTO users
插入无效文档会报错:
aql
INSERT {
name: "张三",
email: "invalid-email",
age: -1
} INTO users
8.2 唯一索引验证 #
创建唯一索引:
javascript
db.users.ensureHashIndex(["email"], { unique: true });
重复插入会报错:
aql
INSERT { name: "张三", email: "zhangsan@example.com" } INTO users
INSERT { name: "李四", email: "zhangsan@example.com" } INTO users
九、实战示例 #
9.1 创建用户并设置默认值 #
aql
INSERT {
name: "张三",
email: "zhangsan@example.com",
status: "active",
role: "user",
createdAt: DATE_NOW(),
updatedAt: DATE_NOW(),
loginCount: 0
} INTO users
RETURN NEW
9.2 从CSV导入 #
aql
LET lines = @csvLines
FOR line IN lines
LET parts = SPLIT(line, ",")
INSERT {
name: parts[0],
email: parts[1],
age: TO_NUMBER(parts[2])
} INTO users
9.3 创建嵌套文档 #
aql
INSERT {
name: "张三",
contact: {
email: "zhangsan@example.com",
phone: "13800138000"
},
address: {
city: "北京",
district: "朝阳区",
street: "朝阳路100号"
},
preferences: {
theme: "dark",
language: "zh-CN"
}
} INTO users
9.4 创建带数组字段的文档 #
aql
INSERT {
name: "张三",
hobbies: ["阅读", "游泳", "编程"],
tags: ["developer", "backend"],
scores: [90, 85, 92, 88]
} INTO users
十、性能优化 #
10.1 批量插入优化 #
aql
FOR i IN 1..10000
INSERT {
name: CONCAT("用户", i),
value: RAND()
} INTO large_collection
OPTIONS { batchSize: 1000 }
10.2 禁用索引后插入 #
javascript
db.large_collection.dropIndex("hash_index_name");
db._query("FOR i IN 1..10000 INSERT { name: CONCAT('用户', i) } INTO large_collection");
db.large_collection.ensureHashIndex(["name"]);
10.3 使用事务批量插入 #
javascript
db._executeTransaction({
collections: { write: ["users"] },
action: function() {
var db = require("@arangodb").db;
for (var i = 0; i < 1000; i++) {
db.users.insert({ name: "用户" + i });
}
}
});
十一、错误处理 #
11.1 忽略错误 #
aql
INSERT {
_key: "existing_key",
name: "张三"
} INTO users
OPTIONS { ignoreErrors: true }
11.2 捕获错误 #
javascript
try {
db.users.insert({
_key: "existing_key",
name: "张三"
});
} catch (e) {
print("插入失败: " + e.message);
}
11.3 条件插入 #
aql
LET exists = DOCUMENT("users", "user_001")
FILTER exists == null
INSERT {
_key: "user_001",
name: "张三"
} INTO users
十二、总结 #
文档插入要点:
- INSERT:基本插入语法
- 批量插入:使用FOR循环提高效率
- UPSERT:存在则更新,不存在则插入
- 选项:waitForSync、overwrite等
- 验证:Schema验证和唯一索引
下一步,让我们学习文档更新!
最后更新:2026-03-27