MongoDB之创建文档
2020-09-05 本文已影响0人
AbstractCulture
文档主键_id
- 唯一标识,不同的文档有不同的主键id.跟MySQL中的primary key类似。
- 文档主键不可以是数组,其他数据结构都可以作为主键。
- 复合主键: 使用文档作为另一个文档的主键
复合主键
注意遵循文档主键唯一的规则
department:{
_id:{
_id: 01,
name: "董事会"
},
name: "技术委员会"
}
对象主键 ObjectId
如果在创建一篇文档的时候不指定主键,那么mongodb客户端会为你自动生成对象主键来作为文档主键.
- 默认的文档主键
- 可以快速生成的12字节id,有序
- 前4个字节为创建时间(精确到秒)
- 同一时间并发创建的文档无法通过ObjectId来区分创建的顺序
- 可能会因为不同客户端的系统时间不一致导致生成的ObjectId一致的情况
获取ObjectId的创建时间
shell> ObjectId('xxx').getTimeStamp()
创建文档
术语名词 | 描述 |
---|---|
collection | 文档将要写入的集合,可以理解成MySQL数据库中的库. |
document | 要写入的文档,可以理解成MySQL中的表. |
writeConcern | 定义了本次文档创建操作的安全写级别. 安全写级别用来判断一次数据库写入操作是否成功, 安全写级别越高,丢失数据的风险就越低,然而写入操作的延迟也可能更高. 如果不指定writeConcern,mongoDB使用默认的安全写级别 |
acknowledged | true表示安全写级别被启用 |
insertedId | 写入的文档主键 |
ordered | 用来决定mongodb是否需要按照顺序来写入文档 false,性能会更好 true, 严格按照顺序写入 默认为true |
nInserted | 当前语句插入成功的数量 |
nUpserted | 当前语句更新成功的数量 |
nMatched | 当前语句匹配成功的数量 |
nModified | 当前语句修改成功的数量 |
nRemoved | 当前语句删除成功的数量 |
创建单个文档
- db.collection.insert()
若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据.可以写入一条或者多条数据
dn.<collection>.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
}
)
- db.collection.save()
如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃.
使用db.collection.save()命令处理一个新文档时,它会去调用db.collection.insert()命令
db.<collection>.save(
<document>,
{
writeConcern: <document>
}
)
- db.collection.insertOne()
db.<collection>.insertOne(
<document>,
{
writeConcern: <document>
}
)
创建多个文档
- db.collection.insertMany
如果在插入的过程中出现了异常,MongoDB会进行中断,不执行后面的插入语句
比如插入10条语句,第5条失败了,后面的5条就不做插入处理了,所以mongo的批量插入是不保证原子性的
db.<collection>.insertMany(
[<document1>,<document2>,....]
{
writeConcern: <document>,
ordered: <boolean>
}
)
shell演示
## 使用test数据库
shell> use test
## 查看test数据库中的集合,返回空白则说明没有任何数据
shell> show collections
## 创建单个文档
shell> db.accounts.insertOne(
{
_id: "test",
name: "测试mongodb插入",
success: true
}
)
## 执行插入语句返回的结果
shell> { "acknowledged" : true, "insertedId" : "test" }
## 查询是否成功
shell> db.accounts.find()
## 测试一下文档主键唯一性
shell> db.accounts.insertOne(
{
_id: "test",
name: "测试mongodb插入",
success: true
}
)
## 返回结果
WriteError({
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.accounts index: _id_ dup key: { _id: \"test\" }",
"op" : {
"_id" : "test",
"name" : "测试mongodb插入",
"success" : true
}
})...省略
## 太乱了,进行try catch打印
shell>
try{
db.accounts.insertOne(
{
_id: "test",
name: "测试mongodb插入",
success: true
}
)
}catch(e){
print(e)
}
## 可见,清爽了不少
## 批量插入文档,注意,批量插入的对象是一个数组
shell>
try{
db.accounts.insertMany(
[{
name: "测试mongodb批量插入1",
success: true
},
{
name: "测试mongodb批量插入2",
success: true
}]
)
}catch(e){
print(e)
}
## 批量插入文档,指定order为false,可以看到在抛出异常的同时,正确的文档仍被写入
shell>
try{
db.accounts.insertMany(
[{
_id: "test",
name: "测试mongodb批量插入1",
success: true
},
{
name: "测试mongodb批量插入2",
success: true
}],
{ordered: false}
)
}catch(e){
print(e)
}
## 使用insert写入单条数据到account集合
shell>
db.accounts.insert(
{
name: "google",
success: true
}
)
## 使用insert写入多条数据到account集合
shell>
db.accounts.insert(
[{
name: "google",
success: true
},
{
name: "baidu",
success: true
}]
)
答疑:为什么我没有创建accounts集合我却能往里面创建文档?
答: 创建或插入操作会将新文档添加到集合中。如果该集合当前不存在,则插入操作将创建该集合。
TIPS: 进行适当的try catch,让报错时的异常变的更清晰易懂
insert、insertMany、insertOne之间的区别
- 执行语句后返回的Result对象不同
- insertOne和insertMany命令不支持
db.collection.explain()
命令,insert支持