# mongodb 命令


<!--more-->


[可以参考菜鸟教程](https://www.runoob.com/mongodb/mongodb-query.html)

## 1.基本操作

```mongo
查看数据库 
	show dbs; 
切换数据库 如果没有对应的数据库则创建 
	use 数据库名; 
创建集合 
	db.createCollection("集合名") 
查看集合 
	show tables; 
	show collections; 
删除集合 
	db.集合名.drop(); 
删除当前数据库 
	db.dropDatabase();
```

## 2.集合操作

### 2.1 添加

```
# 插入单条, 不指定_id,系统会自动生成
db.集合名.insert(文档)

_id 类型是ObjectId 类型是一个12字节 BSON 类型数据，有以下格式：
	前4个字节表示时间戳 ObjectId("对象Id字符串").getTimestamp() 来获取
	接下来的3个字节是机器标识码
	紧接的两个字节由进程id组成（PID）
	最后三个字节是随机数。)
# 插入多条
db.集合名.insert([文档,文档])
```

### 2.2 查询

- 比较条件 db.[col_name].find(条件)

  | 操作     | 条件格式           | 例子                                       | RDBMS中的条件 |
  | -------- | ------------------ | ------------------------------------------ | ------------- |
  | 等于     | {key:value}        | db.col.find({key:value}).pretty()          | Where col=值  |
  | 大于     | {key:{$gt:value}}  | db.col.fifind({字段名:{$gt:值}}).pretty()  | >             |
  | 小于     | {key:{$lt:value}}  | db.col.fifind({字段名:{$lt:值}}).pretty()  | <             |
  | 大于等于 | {key:{$gte:value}} | db.col.fifind({字段名:{$gte:值}}).pretty() | >=            |
  | 小于等于 | {key:{$lte:value}} | db.col.fifind({字段名:{$lte:值}}).pretty() | <=            |
  | 不等于   | {key:{$ne:value}}  | db.col.fifind({字段名:{$ne:值}}).pretty()  | !=            |

- 逻辑条件

  ```
  and 条件 
  MongoDB 的 find() 方法可以传入多个键(key)，每个键(key)以逗号隔开，即常规 SQL 的 AND 条件 
  	db.集合名.find({key1:value1, key2:value2}).pretty() 
  
  or 条件
  	db.集合名.find({$or:[{key1:value1}, {key2:value2}]}).pretty() 
  
  not 条件 
  	db.集合名.find({key:{$not:{$操作符:value}}).pretty()
  ```

- 分页

  db.集合名.fifind({条件}).sort({排序字段:排序方式})).skip(跳过的行数).limit(一页显示多少数据)

### 2.3 更新

```sql
$set ：设置字段值 
$unset :删除指定字段 
$inc：对修改的值进行自增 
db.集合名.update( 
  <query>, 
  <update>, 
  { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } 
)

参数说明： 
query : update的查询条件，类似sql update查询内where后面的。 
update : update的对象和一些更新的操作符（如$set,$inc...）等，也可以理解为sql update中 set后面的 
upsert : 可选，这个参数的意思是，如果不存在update的记录，是否插入objNew,true为插入，默认 是false，不插入。 
multi : 可选，MongoDB 默认是false,只更新找到的第一条记录，如果这个参数为true,就把按条件查 出来多条记录全部更新。 
writeConcern :可选，用来指定mongod对写操作的回执行为比如写的行为是否需要确认。 

举例： db.集合名.update({条件},{$set:{字段名:值}},{multi:true})
```

> writeConcern 包括以下字段： { w: <value>, j: <boolean>, wtimeout: <number> } 
>
> w:指定写操作传播到的成员数量 
>
> 比如： 
>
> - w=1（默认）:则要求得到写操作已经传播到独立的Mongod实例或副本集的primary成员的确认 
>
> - w=0:则不要求确认写操作，可能会返回socket exceptions和 networking errors 
>
> - w="majority":要求得到写操作已经传播到大多数具有存储数据具有投票的（data-bearing voting ）成员（也就是 members[n].votes 值大于0的成员）的确认 
>
> j:要求得到Mongodb的写操作已经写到硬盘日志的确认 
>
> 比如： 
>
> - j=true:要求得到Mongodb(w指定的实例个数)的写操作已经写到硬盘日志的确认。j=true本身并不保证 因为副本集故障而不会回滚。 
>
> wtimeout:指定write concern的时间限制，只适用于w>1的情况 
>
> - wtimeout在超过指定时间后写操作会返回error，即使写操作最后执行成功，当这些写操作返回时， 
>
> - MongoDB不会撤消在wtimeout时间限制之前执行成功的数据修改。 
>
> - 如果未指定wtimeout选项且未指定write concern级别，则写入操作将无限期阻止。 指定wtimeout值 为0等同于没有wtimeout选项。 

### 2.4 删除

```
db.collection.remove( 
	<query>, 
	{ justOne: <boolean>, writeConcern: <document> } )

参数说明： 
query :（可选）删除的文档的条件。
justOne : （可选）如果设为 true 或 1，则只删除一个文档，如果不设置该参数，或使用默认值 false，则删除所有匹配条件的文档。 writeConcern :（可选）用来指定mongod对写操作的回执行为。
```



## 3.聚合操作

聚合是MongoDB的高级查询语言，它允许我们通过转化合并由多个文档的数据来生成新的在单个文档里不存在的文档信息。一般都是将记录按条件分组之后进行一系列求最大值，最小值，平均值的简单操作，也可以对记录进行复杂数据统计，数据挖掘的操作。聚合操作的输入是集中的文档，输出可以是一个文档也可以是多个文档。

### 3.1 聚合操作分类

- 单目的聚合操作(Single Purpose Aggregation Operation)
- 聚合管道(Aggregation Pipeline)
- MapReduce编程模型

### 3.2 单目的聚合

单目的聚合命令常用的有：count()和distinct()

`db.lg_resume_preview.find({}).count()`

### 3.3 聚合管道

```
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION) 

如: 
db.lg_resume_preview.aggregate([{$group:{_id:"$city",city_count:{$sum:1}}}])
```

MongoDB中聚合(aggregate)主要用于统计数据(诸如统计平均值,求和等)，并返回计算后的数据结果。

表达式：处理输入文档并输出。表达式只能用于计算当前聚合管道的文档，不能处理其它的文档。

![示意图](https://img.zhaojq.top/20260727091648966.png "示意图")

MongoDB 中使用 db.COLLECTION_NAME.aggregate([{},...]) 方法来构建和使用聚合管道，每个文档通过一个由**一个或者多个阶段**（stage）组成的**管道**，经过一系列的处理，输出相应的结果。

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

- $group：将集合中的文档分组，可用于统计结果。

- $project：修改输入文档的结构。可以用来重命名、增加或删除域，也可以用于创建计算结果以及嵌套文档。

- `$match`：用于过滤数据，只输出符合条件的文档。$match使用MongoDB的标准查询操作。

- $limit：用来限制MongoDB聚合管道返回的文档数。

- $skip：在聚合管道中跳过指定数量的文档，并返回余下的文档。

- $sort：将输入文档排序后输出。

- $geoNear：输出接近某一地理位置的有序文档。

> ```
> db.lg_resume_preview.aggregate( 
> [{$group : {_id: "$city", avgSal:{$avg:"$expectSalary"}}}, 
>  {$project : {city: "$city", salary : "$avgSal"}} 
> ])
> ```
>
> ```
> db.lg_resume_preview.aggregate( 
> [{$group:{_id: "$city",count:{$sum : 1}}}, 
>  {$match:{count:{$gt:1}}} 
> ])
> ```

### 3.4 mapReduce编程模型

Pipeline查询速度快于MapReduce，但是MapReduce的强大之处在于能够在多台Server上并行执行复杂的聚合逻辑。MongoDB不允许Pipeline的单个聚合操作占用过多的系统内存，如果一个聚合操作消耗20%以上的内存，那么MongoDB直接停止操作，并向客户端输出错误消息。

MapReduce是一种计算模型，简单的说就是将大批量的工作（数据）分解（MAP）执行，然后再将结果合并成最终结果（REDUCE）。

```
>db.collection.mapReduce( 
	function() {emit(key,value);}, //map 函数 
	function(key,values) {return reduceFunction}, //reduce 函数 
	{ 
		out: collection, 
		query: document, 
		sort: document, 
		limit: number, 
		finalize: <function>, 
		verbose: <boolean> 
		} 
)

# 使用 MapReduce 要实现两个函数 Map 函数和 Reduce 函数,
Map 函数调用 emit(key, value), 遍历collection 中所有的记录, 
将 key 与 value 传递给 Reduce 函数进行处理。
```

- map：是JavaScript 函数，负责将每一个输入文档转换为零或多个文档，生成键值对序列,作为reduce 函数参数

- reduce：是JavaScript 函数，对map操作的输出做合并的化简的操作（将key-value变成keyvalues，也就是把values数组变成一个单一的值value） 
- out：统计结果存放集合
- query： 一个筛选条件，只有满足条件的文档才会调用map函数。
- sort： 和limit结合的sort排序参数（也是在发往map函数前给文档排序），可以优化分组机制
- limit： 发往map函数的文档数量的上限（要是没有limit，单独使用sort的用处不大）
- fifinalize：可以对reduce输出结果再一次修改
- verbose：是否包括结果信息中的时间信息，默认为fasle

