一、创建文档
1. 进入Mongo shell
# 使用test数据库
> use test
switched to db test
# 查看test数据库中的集合
> show collections
2. 创建一个文档
db.<集合名>.inserOne(文档内容) 命令会自动创建相应的集合
> db.accounts.insertOne(
... {
... _id: "account1",
... name: "alice",
... balance: 100
... }
... )
{ "acknowledged" : true, "insertedId" : "account1" }
{ "acknowledged" : true, "insertedId" : "account1" }:- 是返回的结果
- "acknowledged": true表示安全写级别被启用
- "insertedId":显示了被写入的文档的_id
2.1 使用重复的_id创建一个新文档会造成错误
# 为了方便查看错误信息,最好加上try catch
try{
db.accounts.insertOne(
{
_id:"account1",
name:"bob",
balance: 50
}
)
}catch(e) {
print(e)
}
# 错误
WriteError({
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.accounts index: _id_ dup key: { _id: \"account1\" }",
"op" : {
"_id" : "account1",
"name" : "bob",
"balance" : 50
}
2.2 自动生成_id
省略创建文档中的_id字段
db.accounts.insertOne(
{
name:"bob",
balance:50
}
)
# 返回结果
{
"acknowledged" : true,
"insertedId" : ObjectId("63bd080fef3b5e682a151ff8")# 自动生成的文档主键
}
3. 创建多个文档
db.collection.insertMany()
db.<collection>.insertMany(
[<document1>,<document2>,...],
{
writeConcern:<document>,
ordered:<boolean>
}
)
ordered参数用来决定mongoDB 是否按顺序来写入这些文档
ordered设置为false,则打乱文档写入的顺序,以便优化写入操作的性能,默认为true
db.accounts.insertMany(
[
{
name:"charlie",
balance:500
},
{
name:"david",
balance:200
}
]
)
# 返回结果
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("63bd1a23ef3b5e682a151ff9"),
ObjectId("63bd1a23ef3b5e682a151ffa")
]
}
使用重复的_id,顺序写入时遇到的错误
# # 第一个文档用重复的_id
try{
db.accounts.insertMany(
[
{
_id:"account1",
name:"edwrad",
balance:700
},
{
name:"david",
balance:20
}
]
)
} catch(e) {
print(e)
}
# 报错信息
BulkWriteError({
"writeErrors" : [
{
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.accounts index: _id_ dup key: { _id: \"account1\" }",
"op" : {
"_id" : "account1",
"name" : "edwrad",
"balance" : 700
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 0, # 因为是顺序写入,所以一篇都没插进去,直接开始报错了,所以是0
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
使用重复_id,乱序写入时遇到的错误
# 设置为乱序
try{
db.accounts.insertMany(
[
{
_id:"account1",
name:"edwrad",
balance:700
},
{
name:"david",
balance:20
}
],{ ordered:false }
)
} catch(e) {
print(e)
}
# 报错信息
BulkWriteError({
"writeErrors" : [
{
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.accounts index: _id_ dup key: { _id: \"account1\" }",
"op" : {
"_id" : "account1",
"name" : "edwrad",
"balance" : 700
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 1, # 因为是乱序写入,第二篇成功了,第一篇失败了,所以成功插入数量为1
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
在顺序写入时,一旦遇到错误,操作便会退出,剩余的文档无论正确与否,都不会被写入。
在乱序写入时。即使某些文档造成了错误,剩余得正确文档仍然会被写入
4. 创建一个或多个文档
db.collection.insert()
db.<collection>.insert(
<document or array of documents>,# 一个或多个文档
{
writeConcern:<document>,
ordered:<boolean>
}
)
将文档吸入accounts集合
db.accounts.insert(
{
name:"george",
balance:1000
}
)
# 只返回写入文档的数量
WriteResult({ "nInserted" : 1 })
使用insert插入重复的_id
try{
db.accounts.insert(
[
{
_id:"account1",
name:"george",
balance:1000
},
{
name:"henry",
balance:2000
}
]
)
} catch(e){
print(e)
}
# 报错
BulkWriteResult({
"writeErrors" : [
{
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.accounts index: _id_ dup key: { _id: \"account1\" }",
"op" : {
"_id" : "account1",
"name" : "george",
"balance" : 1000
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 0, # 跟之前的顺序插入多个一样
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
5. insertOne,insertMany和insert的区别
- 返回的结果文档格式不一样(具体看上面例子)
insertOne和insertMany命令不支持db.collection.explain()命令,但是insert支持
6. 另一个创建文档的命令
db.collection.save()
db.<collection>.save(
<document>,
{
writeConcern:<document>
}
)
当这个命令处理一个新文档的时候,它会调用insert()命令,且返回的结果文档与insert()一样
6. 文档主键_id
在不主动指定_id的情况下,默认的对象主键objectId
# 创建一个主键
> ObjectId()
ObjectId("63bd2997ef3b5e682a151fff")
# 知道主键id并查看
> ObjectId("63bd2997ef3b5e682a151fff")
ObjectId("63bd2997ef3b5e682a151fff")
# 提取ObjectId的创建时间
> ObjectId("63bd2997ef3b5e682a151fff").getTimestamp()
ISODate("2023-01-10T09:02:15Z")
7. 复合主键
- 可以使用文档作为文档主键
# _id本身就是一个文档
db.accounts.insert(
{
_id:{ accountNo:"001",type:"savings"},
name:"irene",
balance:80
}
)
- 复合主键仍然要满足文档主键的唯一性
- 当复合主键的文档内容一样,但是顺序不一样时,也满足唯一性
# 顺序不同,两个复合id依旧满足唯一性
_id:{ accountNo:"001",type:"savings"}
_id:{ type:"savings",accountNo:"001"}
8. 总结
- 使用
db.collection.insertOne()创建单一文档 - 使用
db.collection.insertMany()创建多个文档 - 使用
db.collection.insert()创建单一或多个文档 - 创建文档命令返回的结果/错误
- 使用
db.collection.save()创建单一文档 - 对象主键ObjectId
- 复合主键