mongodb

## 命令行操作
# mongo 数据库操作
# 进入数据库
mongo --host host --port port -u username -p password --authenticationDatabase admin databaseName
# 或者
mongo --host host --port port -u username -p password --authenticationDatabase admin

# 查看数据库
show dbs
# 查看当前数据库
db
# 创建数据库
use databaseName
# 创建集合
db.createCollection("collectionName")
# 查看集合
show collections
# 查看集合数据
db.collection.find()
# 修改数据
db.collection.update()
# 删除数据
db.collection.remove()
# 删除集合
db.collection.drop()
# 删除数据库
db.dropDatabase();

## 数据查询
# 查找数据
db.collection.find() # 相当于 select * from collection
db.collection.find({key: value}) # 相当于 select * from collection where key = value

# 查询去掉重复数据
db.collection.distinct("key")

# 查询age=22 数据
db.collection.find({age: 22})
# 查询age>22 数据
db.collection.find({age: {$gt: 22}})
# 查询age>=22 数据
db.collection.find({age: {$gte: 22}})
# 查询age<22 数据
db.collection.find({age: {$lt: 22}})
# 查询age<=22 数据
db.collection.find({age: {$lte: 22}})
# 查询age!=22 数据
db.collection.find({age: {$ne: 22}})

# 查询age=22 数据, 并且只显示name, age
db.collection.find({age: 22}, {name: 1, age: 1})

# 模糊查询: 查询name中包含"张"的数据
db.collection.find({name: /张/}) # 相当于 select * from collection where name like '%张%'

# 查询name中以"张"开头的数据
db.collection.find({name: /^张/}) # 相当于 select * from collection where name like '张%'

# 升序 1  , 降序

# 查询age=22 数据, 并且只显示name, age, 并且按照age升序排列
db.collection.find({age: 22}, {name: 1, age: 1}).sort({age: 1})
# 查询age=22 数据, 并且只显示name, age, 并且按照age降序排列
db.collection.find({age: 22}, {name: 1, age: 1}).sort({age: -1})

# 查询 前5条数据
db.collection.find().limit(5)
# 查询 跳过前5条数据
db.collection.find().skip(5)

# 分页, limit: pageSize, skip: (pageNo - 1) * pageSize
db.collection.find().limit(5).skip(5)

# or 查询
db.collection.find({$or: [{age: 22}, {age: 23}]}) # 相当于 select * from collection where age = 22 or age = 23

# and 查询
db.collection.find({$and: [{age: 22}, {name: "张三"}]}) # 相当于 select * from collection where age = 22 and name = "张三"

# in 查询
db.collection.find({age: {$in: [22, 23]}}) # 相当于 select * from collection where age in (22, 23)

# not in 查询
db.collection.find({age: {$nin: [22, 23]}}) # 相当于 select * from collection where age not in (22, 23)

# findOne
db.collection.findOne({age: 22}) # 相当于 select * from collection where age = 22 limit 1

# 统计条数
db.collection.count();

# 加条件 统计条数
db.collection.find({age: {$gte: 22}}).count();

# 如果要返回线坠之后的记录数量
db.collection.find({age: {$gte: 22}}).skip(5).limit(5).count(true)



## 修改数据
# 修改一条数据
db.collection.update({age: 22}, {$set: {age: 23}}) # 相当于 update collection set age = 23 where age = 22 limit 1

# 更改所有匹配的项目
db.collection.update({age: 22}, {$set: {age: 23}}, {multi: true}) # 相当于 update collection set age = 23 where age = 22

# 完整替换 一条数据, 不出现 $set
db.collection.update({age: 22}, {name: "张三", age: 23}) # 相当于 update collection set name = "张三", age = 23 where age = 22 limit 1

# $inc 增加
db.collection.update({age: 22}, {$inc: {age: 1}}, false, true ) # 相当于 update collection set age = age + 1 where age = 22 limit 1

# $inc 与 $set 同时使用
db.collection.update({age: 22}, {$inc: {age: 1}, $set: {name: "张三"}}, false, true ) # 相当于 update collection set age = age + 1, name = "张三" where age = 22 limit 1


## 删除数据
# 删除一条数据
db.collection.remove({age: 22}) # 相当于 delete from collection where age = 22 limit 1
# justOne: true 只删除一条数据
db.collection.remove({age: 22}, true) # 相当于 delete from collection where age = 22 limit 1



## 索引
# 索引: 随着集合增长,针对查询的效率会降低,索引可以提高查询效率
# 如果没有对索引的键调用 sort() 方法,MongoDB 会在内部自动对索引键进行排序。
# 因此在做无索引排序时,应该使用与索引相同的顺序,以避免额外的排序操作,否则数据量多大以致无法在内存中进行排序,就会导致严重的性能问题,会导致mongodb 崩溃报错。

# 创建索引
db.collection.createIndex({age: 1}) # 1 升序, -1 降序
# 获取当前集合的索引
db.collection.getIndexes();
# 删除索引
db.collection.dropIndex({age: 1})

# 复合索引
# 复合索引: age 升序, name 升序
db.collection.ensureIndex({age: 1, name: 1}) # 1 升序, -1 降序

# 唯一索引: age 唯一 不能重复
db.collection.ensureIndex({age: 1}, {unique: true}) # 1 升序, -1 降序

# 索引参数
# background: true 后台创建索引, 这样创建索引不会阻塞其他数据库操作,但是会消耗更多的资源。
# dropDups: true 删除重复的索引
# sparse: true 稀疏索引,只包含有索引字段的文档
# unique: true 唯一索引,不能重复
# name: "age" 索引名称



## explain: 查看查询计划
# explain: 查看查询计划
# 返回的结果中, queryPlanner 代表查询计划, winningPlan 代表最终执行的计划, executionStats 代表执行的统计信息
# serverInfo 代表服务器信息, rejectPlans 代表被拒绝的计划

# 具体的执行时间
db.collection.find({age: 22}).explain("executionStats")


## 集合 与 集合之间的关系
# 一对一 关系
# 例如: 用户表,身份证表
# 一对一 关系,可以将两个集合合并成一个集合
# 用户集合: {name: "张三", age: 22, idCard: {idCardNo: "1234567890", address: "北京市"}}
# 身份证集合: {idCardNo: "1234567890", address: "北京市"}
# 查询用户信息,包含身份证信息
db.collection.find({name: "张三"}).populate("idCard")


# 一对多 关系
# 例如: 用户表,订单表
# 用户集合: {name: "张三", age: 22, orders: [{orderNo: "1234567890", price: 100}, {orderNo: "1234567891", price: 200}]}
# 订单集合: {orderNo: "1234567890", price: 100, userId: "1234567890"}
# 查询用户信息,包含订单信息
db.collection.find({name: "张三"}).populate("orders")


# 多对多 关系
# 例如: 用户表,商品表
# 用户集合: {name: "张三", age: 22, products: [{productName: "苹果", price: 100}, {productName: "香蕉", price: 200}]}
# 商品集合: {productName: "苹果", price: 100, userIds: ["1234567890", "1234567891"]}
# 查询用户信息,包含商品信息
db.collection.find({name: "张三"}).populate("products")
# 查询商品信息,包含用户信息
db.collection.find({productName: "苹果"}).populate("userIds")



## 高级查询 aggregate 聚合查询

# aggregate 聚合查询: 表关联查询,数据统计
# 使用 db.collection.aggregate() 方法来执行聚合操作

## 聚合管道操作符与表达式
# $project: 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。 相当于mysql: select
db.collection.aggregate([{$project: {name: 1, age: 1}}])
# $match: 用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。 相当于mysql: where
db.collection.aggregate([{$match: {age: 22}}])
# $limit: 用来限制MongoDB聚合管道返回的文档数。 相当于mysql: limit
db.collection.aggregate([{$limit: 5}])
# $skip: 在聚合管道中跳过指定数量的文档,并返回余下的文档。
db.collection.aggregate([{$skip: 5}])
# $sort : 将输入文档排序后输出。 相当于mysql: order by
db.collection.aggregate([{$sort: {age: 1}}])
# $group: 将集合中的文档分组,可用于统计结果。 相当于mysql: group by
db.collection.aggregate([{$group: {_id: "$age", count: {$sum: 1}}}])
# $lookup: 对集合中的每个文档执行左连接,将其他集合中匹配的文档添加到输出文档中。 相当于mysql: left join
db.collection.aggregate([{$lookup: {from: "orders", localField: "name", foreignField: "name", as: "orderList"}}])
# $sum: 计算总和。 相当于mysql: sum
db.collection.aggregate([{$group: {_id: "$age", count: {$sum: 1}}}])




# 备份数据
mongodump -h dbhost -d dbname -o dbdirectory
# 例如: mongodump -h localhost:27017 -d test -u test -p testpwd -o D:\dump
# 恢复数据
mongorestore -h dbhost -d dbname --dir dbdirectory
#例如: mongorestore -h localhost:27017 -d test -c order --dir d:\dump\test\test.bson -u test -p testpwd