update docs

pull/3/head
dunwu 2020-09-25 21:23:41 +08:00
parent 093e96c675
commit 5a85d01bcd
11 changed files with 344 additions and 23 deletions

Binary file not shown.

View File

@ -10,6 +10,8 @@
### [MongoDB 应用指南](mongodb-quickstart.md)
### [MongoDB CRUD 操作](mongodb-crud.md)
### [MongoDB 聚合操作](mongodb-aggregation.md)
### [MongoDB 建模](mongodb-model.md)
@ -28,7 +30,7 @@
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -377,7 +377,7 @@ SQL 和 MongoDB 聚合方式对比:
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -0,0 +1,320 @@
# MongoDB CRUD 操作
<!-- TOC depthFrom:2 depthTo:3 -->
<!-- /TOC -->
## 一、基本 CRUD 操作
MongoDB 的 CRUD 操作是针对 document 的读写操作。
### Create 操作
MongoDB 提供以下操作向一个 collection 插入 document
- [`db.collection.insertOne()`](https://docs.mongodb.com/manual/reference/method/db.collection.insertOne/#db.collection.insertOne):插入一条 document
- [`db.collection.insertMany()`](https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/#db.collection.insertMany):插入多条 document
> 注:以上操作都是原子操作。
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924112342.svg)
插入操作的特性:
- MongoDB 中的所有写操作都是单个文档级别的原子操作。
- 如果要插入的 collection 当前不存在,则插入操作会自动创建 collection。
- 在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 [`_id`](https://docs.mongodb.com/manual/reference/glossary/#term-id) 字段作为主键。如果插入的文档省略 `_id` 字段,则 MongoDB 驱动程序会自动为 `_id` 字段生成 ObjectId。
- 可以 MongoDB 写入操作的确认级别来控制写入行为。
【示例】插入一条 document 示例
```javascript
db.inventory.insertOne({
item: 'canvas',
qty: 100,
tags: ['cotton'],
size: { h: 28, w: 35.5, uom: 'cm' },
})
```
【示例】插入多条 document 示例
```javascript
db.inventory.insertMany([
{
item: 'journal',
qty: 25,
tags: ['blank', 'red'],
size: { h: 14, w: 21, uom: 'cm' },
},
{
item: 'mat',
qty: 85,
tags: ['gray'],
size: { h: 27.9, w: 35.5, uom: 'cm' },
},
{
item: 'mousepad',
qty: 25,
tags: ['gel', 'blue'],
size: { h: 19, w: 22.85, uom: 'cm' },
},
])
```
### Read 操作
MongoDB 提供 [`db.collection.find()`](https://docs.mongodb.com/manual/reference/method/db.collection.find/#db.collection.find) 方法来检索 document。
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924113832.svg)
### Update 操作
MongoDB 提供以下操作来更新 collection 中的 document
- [`db.collection.updateOne()`](https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/#db.collection.updateOne):更新一条 document
- [`db.collection.updateMany()`](https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#db.collection.updateMany):更新多条 document
- [`db.collection.replaceOne()`](https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#db.collection.replaceOne):替换一条 document
语法格式:
- [`db.collection.updateOne(<filter>, <update>, <options>)`](https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/#db.collection.updateOne)
- [`db.collection.updateMany(<filter>, <update>, <options>)`](https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#db.collection.updateMany)
- [`db.collection.replaceOne(<filter>, <update>, <options>)`](https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#db.collection.replaceOne)
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924114043.svg)
【示例】插入测试数据
```javascript
db.inventory.insertMany([
{
item: 'canvas',
qty: 100,
size: { h: 28, w: 35.5, uom: 'cm' },
status: 'A',
},
{ item: 'journal', qty: 25, size: { h: 14, w: 21, uom: 'cm' }, status: 'A' },
{ item: 'mat', qty: 85, size: { h: 27.9, w: 35.5, uom: 'cm' }, status: 'A' },
{
item: 'mousepad',
qty: 25,
size: { h: 19, w: 22.85, uom: 'cm' },
status: 'P',
},
{
item: 'notebook',
qty: 50,
size: { h: 8.5, w: 11, uom: 'in' },
status: 'P',
},
{ item: 'paper', qty: 100, size: { h: 8.5, w: 11, uom: 'in' }, status: 'D' },
{
item: 'planner',
qty: 75,
size: { h: 22.85, w: 30, uom: 'cm' },
status: 'D',
},
{
item: 'postcard',
qty: 45,
size: { h: 10, w: 15.25, uom: 'cm' },
status: 'A',
},
{
item: 'sketchbook',
qty: 80,
size: { h: 14, w: 21, uom: 'cm' },
status: 'A',
},
{
item: 'sketch pad',
qty: 95,
size: { h: 22.85, w: 30.5, uom: 'cm' },
status: 'A',
},
])
```
【示例】更新一条 document
```javascript
db.inventory.updateOne(
{ item: 'paper' },
{
$set: { 'size.uom': 'cm', status: 'P' },
$currentDate: { lastModified: true },
}
)
```
【示例】更新多条 document
```javascript
db.inventory.updateMany(
{ qty: { $lt: 50 } },
{
$set: { 'size.uom': 'in', status: 'P' },
$currentDate: { lastModified: true },
}
)
```
【示例】替换一条 document
```javascript
db.inventory.replaceOne(
{ item: 'paper' },
{
item: 'paper',
instock: [
{ warehouse: 'A', qty: 60 },
{ warehouse: 'B', qty: 40 },
],
}
)
```
更新操作的特性:
- MongoDB 中的所有写操作都是单个文档级别的原子操作。
- 一旦设置了,就无法更新或替换 [`_id`](https://docs.mongodb.com/manual/reference/glossary/#term-id) 字段。
- 除以下情况外MongoDB 会在执行写操作后保留文档字段的顺序:
- `_id` 字段始终是文档中的第一个字段。
- 包括重命名字段名称的更新可能导致文档中字段的重新排序。
- 如果更新操作中包含 `upsert : true` 并且没有 document 匹配过滤器MongoDB 会新插入一个 document如果有匹配的 documentMongoDB 会修改或替换这些 document。
### Delete 操作
MongoDB 提供以下操作来删除 collection 中的 document
- [`db.collection.deleteOne()`](https://docs.mongodb.com/manual/reference/method/db.collection.deleteOne/#db.collection.deleteOne):删除一条 document
- [`db.collection.deleteMany()`](https://docs.mongodb.com/manual/reference/method/db.collection.deleteMany/#db.collection.deleteMany):删除多条 document
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924120007.svg)
删除操作的特性:
- MongoDB 中的所有写操作都是单个文档级别的原子操作。
## 二、批量写操作
MongoDB 通过 [`db.collection.bulkWrite()`](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) 方法来支持批量写操作(包括批量插入、更新、删除)。
此外,[`db.collection.insertMany()`](https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/#db.collection.insertMany) 方法支持批量插入操作。
### 有序和无序的操作
批量写操作可以有序或无序。
- 对于有序列表MongoDB 串行执行操作。如果在写操作的处理过程中发生错误MongoDB 将不处理列表中剩余的写操作。
- 对于无序列表MongoDB 可以并行执行操作但是不能保证此行为。如果在写操作的处理过程中发生错误MongoDB 将继续处理列表中剩余的写操作。
在分片集合上执行操作的有序列表通常比执行无序列表要慢,因为对于有序列表,每个操作必须等待上一个操作完成。
默认情况下,[`bulkWrite()`](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) 执行有序操作。要指定无序写操作,请在选项文档中设置 `ordered : false`
### bulkWrite() 方法
[`bulkWrite()`](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) 支持以下写操作:
- [insertOne](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-insertone)
- [updateOne](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-updateonemany)
- [updateMany](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-updateonemany)
- [replaceOne](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-replaceone)
- [deleteOne](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-deleteonemany)
- [deleteMany](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-deleteonemany)
【示例】批量写操作示例
```javascript
try {
db.characters.bulkWrite([
{
insertOne: {
document: {
_id: 4,
char: 'Dithras',
class: 'barbarian',
lvl: 4,
},
},
},
{
insertOne: {
document: {
_id: 5,
char: 'Taeln',
class: 'fighter',
lvl: 3,
},
},
},
{
updateOne: {
filter: { char: 'Eldon' },
update: { $set: { status: 'Critical Injury' } },
},
},
{ deleteOne: { filter: { char: 'Brisbane' } } },
{
replaceOne: {
filter: { char: 'Meldane' },
replacement: { char: 'Tanys', class: 'oracle', lvl: 4 },
},
},
])
} catch (e) {
print(e)
}
```
### 批量写操作策略
大量的插入操作(包括初始数据插入或常规数据导入)可能会影响分片集群的性能。对于批量插入,请考虑以下策略:
#### 预拆分 collection
如果分片集合为空,则该集合只有一个初始 [chunk](https://docs.mongodb.com/manual/reference/glossary/#term-chunk),该 [chunk](https://docs.mongodb.com/manual/reference/glossary/#term-chunk) 位于单个分片上。然后MongoDB 必须花一些时间来接收数据,创建拆分并将拆分的块分发到可用的分片。为了避免这种性能成本,您可以按照拆分群集中的拆分块中的说明预拆分 collection。
#### 无序写操作
要提高对分片集群的写入性能,请使用 [`bulkWrite()`](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite),并将可选参数顺序设置为 false。[`mongos`](https://docs.mongodb.com/manual/reference/program/mongos/#bin.mongos) 可以尝试同时将写入操作发送到多个分片。对于空集合,首先按照分片群集中的分割 [chunk](https://docs.mongodb.com/manual/reference/glossary/#term-chunk) 中的说明预拆分 collection。
#### 避免单调节流
如果在一次插入操作中,分片 key 单调递增,那么所有的插入数据都会存入 collection 的最后一个 chunk也就是存入一个分片中。因此集群的插入容量将永远不会超过该单个分片的插入容量。
如果插入量大于单个分片可以处理的插入量,并且无法避免单调递增的分片键,那么请考虑对应用程序进行以下修改:
- 反转分片密钥的二进制位。这样可以保留信息,并避免将插入顺序与值序列的增加关联起来。
- 交换第一个和最后一个 16 位字以“随机”插入。
## SQL 和 MongoDB 对比
### 术语和概念
| SQL 术语和概念 | MongoDB 术语和概念 |
| :-------------------------- | :----------------------------------------------------------- |
| database | [database](https://docs.mongodb.com/manual/reference/glossary/#term-database) |
| table | [collection](https://docs.mongodb.com/manual/reference/glossary/#term-collection) |
| row | [document](https://docs.mongodb.com/manual/reference/glossary/#term-document) 或 [BSON](https://docs.mongodb.com/manual/reference/glossary/#term-bson) |
| column | [field](https://docs.mongodb.com/manual/reference/glossary/#term-field) |
| index | [index](https://docs.mongodb.com/manual/reference/glossary/#term-index) |
| table joins | [`$lookup`](https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#pipe._S_lookup)、嵌入式文档 |
| primary key | [primary key](https://docs.mongodb.com/manual/reference/glossary/#term-primary-key)<br>MongoDB 中自动设置主键为 [`_id`](https://docs.mongodb.com/manual/reference/glossary/#term-id) 字段 |
| aggregation (e.g. group by) | aggregation pipeline<br>参考 [SQL to Aggregation Mapping Chart](https://docs.mongodb.com/manual/reference/sql-aggregation-comparison/). |
| SELECT INTO NEW_TABLE | [`$out`](https://docs.mongodb.com/manual/reference/operator/aggregation/out/#pipe._S_out)<br>参考 [SQL to Aggregation Mapping Chart](https://docs.mongodb.com/manual/reference/sql-aggregation-comparison/) |
| MERGE INTO TABLE | [`$merge`](https://docs.mongodb.com/manual/reference/operator/aggregation/merge/#pipe._S_merge) (MongoDB 4.2 开始支持)<br>参考 [SQL to Aggregation Mapping Chart](https://docs.mongodb.com/manual/reference/sql-aggregation-comparison/). |
| UNION ALL | [`$unionWith`](https://docs.mongodb.com/manual/reference/operator/aggregation/unionWith/#pipe._S_unionWith) (MongoDB 4.4 开始支持) |
| transactions | [transactions](https://docs.mongodb.com/manual/core/transactions/) |
## 参考资料
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)
- [MongoDB 高手课](https://time.geekbang.org/course/intro/100040001)

View File

@ -18,7 +18,7 @@
**MongoDB 使用 `createIndex()` 方法来创建索引**。
`createIndex()` 语法如下:
`createIndex()` 语法如下:
```javascript
db.collection.createIndex( <key and index type specification>, <options> )
@ -26,18 +26,18 @@ db.collection.createIndex( <key and index type specification>, <options> )
`createIndex()` 可选参数列表如下:
| Parameter | Type | Description |
| :----------------- | :------------ | :----------------------------------------------------------- |
| background | Boolean | 建索引过程会阻塞其它数据库操作background可指定以后台方式创建索引即增加 "background" 可选参数。 "background" 默认值为**false**。 |
| unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为**false**. |
| name | string | 索引的名称。如果未指定MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
| dropDups | Boolean | **3.0+版本已废弃。**在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 **false**. |
| sparse | Boolean | 对文档中不存在的字段数据不启用索引这个参数需要特别注意如果设置为true的话在索引字段中不会查询出不包含对应字段的文档.。默认值为 **false**. |
| expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定设定集合的生存时间。 |
| v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 |
| weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
| default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
| language_override | string | 对于文本索引该参数指定了包含在文档中的字段名语言覆盖默认的language默认值为 language. |
| Parameter | Type | Description |
| :----------------- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| background | Boolean | 建索引过程会阻塞其它数据库操作background 可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为**false**。 |
| unique | Boolean | 建立的索引是否唯一。指定为 true 创建唯一索引。默认值为**false**. |
| name | string | 索引的名称。如果未指定MongoDB 的通过连接索引的字段名和排序顺序生成一个索引名称。 |
| dropDups | Boolean | **3.0+版本已废弃。**在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 **false**. |
| sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为 true 的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 **false**. |
| expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL 设定,设定集合的生存时间。 |
| v | index version | 索引的版本号。默认的索引版本取决于 mongod 创建索引时运行的版本。 |
| weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
| default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
| language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的 language默认值为 language. |
【示例】使用 name 作为索引,并且按照降序排序
@ -49,7 +49,7 @@ db.collection.createIndex( { name: -1 } )
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -385,7 +385,7 @@ MongoDB 允许这条操作执行,但是服务器会记录下告警信息。
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -295,7 +295,6 @@ $ mongoexport -h 127.0.0.1 --port 27017 -d test -c product --type csv -f name,pr
## 参考资料
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -678,5 +678,5 @@ db.<集合>.aggregate(pipeline, {options});
## 参考资料
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -105,7 +105,7 @@ MongoDB 中的副本集是一组维护相同数据集的 mongod 进程。一个
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)

View File

@ -65,7 +65,7 @@ MongoDB 数据库可以同时包含分片和未分片的集合的 collection。
- 选择合适数据节点进行读写
- 合并多个数据节点的返回
一般,路由节点 mongos 建议至少 2个。
一般,路由节点 mongos 建议至少 2 个。
## 分片 Key
@ -135,7 +135,7 @@ Hash 分片策略会先计算分片 Key 字段值的哈希值;然后,根据
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDBGithub](https://github.com/mongodb/mongo)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)