前言
大家好,我是小郭,今天主要为大家提供一条龙服务,从Mongo DB的简介到实战使用,使我们面对技术选型的时候可以得心应手。
Mongo DB简介
网络异常,图片无法展示
|
MongoDB是一个文档数据库(以Json为数据模型),旨在简化应用程序开发和扩展,介于关系型数据库和非关系型之间。MongoDB中的记录是一个文档,它是一个由字段和值对组成的数据结构。
网络异常,图片无法展示
|
特点
- 原生高可用
网络异常,图片无法展示
|
- 横向扩展能力
网络异常,图片无法展示
|
- 无缝扩展
- 应用全透明
- 多种数据分布策略
应用场景
- 共享单车,存储位置信息
- 大文本JSON,记录应用服务器的日志记录
MongoDB 安装
MongoDB为我们提供多种的方案,灵活选择安装方式
Docker方式安装
docker pull mongo:5.0 docker run \ --name mongo \ -p 27017:27017 \ -v /Users/xxx/soft/mongodb/configdb:/data/configdb/ \ -v /Users/xxx/soft/mongodb/db/:/data/db/ \ -d mongo:5.0 --auth # 进入容器 docker exec -it 6b594bf79827 bash # 连接mongo mongo
网络异常,图片无法展示
|
MongoDB Atlas 搭建集群
可以参考下mongodb为我们提供的方案
搭建完之后可以看到整个集群的状态
网络异常,图片无法展示
|
MongoDB基础概念和操作
SQL概念 | MongoDB概念 |
database | database |
table | collection |
row | document |
column | field |
index | index |
primary key | primary key(MongoDB自动将_id设置为主键) |
数据库和集群
数据库操作
show dbs # 查看所有库 use myDB # 如果没有这个数据库会新建一个 db.dropDatabase() # 删除当前数据库
Collection
MongoDB将文档存储在集合中。集合类似于关系数据库中的表。
网络异常,图片无法展示
|
# 查看集合 show collections # 创建集合 db.createCollection("myNewCollection1") # 创建集合如果集合不存在 db.myNewCollection2.insertOne( { x: 1 } ) # 删除集合 db.myNewCollection1.drop() # 集合详细信息 db.getCollectionInfos()
Document
- 单个文档
db.inventory.insertOne( { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } } )
网络异常,图片无法展示
|
_id是MongoDB默认指定的一个主键,我们插入的时候也可以自己指定id的值
网络异常,图片无法展示
|
- 多个文档
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" } } ])
常用查询
MongoDB | SQL |
db.inventory.find( {} ) | SELECT * FROM inventory |
db.inventory.find( { status: "D" } ) | SELECT * FROM inventory WHERE status = "D" |
db.inventory.find( { status: { $in: [ "A", "D" ] } } ) | SELECT * FROM inventory WHERE status in ("A", "D") |
db.inventory.find( { status: "A", qty: { $lt: 30 } } ) | SELECT * FROM inventory WHERE status = "A" AND qty < 30 |
db.inventory.find( { or: [ { status: "A" }, { qty: { lt: 30 } } ] } ) | SELECT * FROM inventory WHERE status = "A" OR qty < 30 |
db.inventory.find( { status: "A", or: [ { qty: { lt: 30 } }, { item: /^p/ } ] } ) |
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%") |
查询条件对照表
SQL | MQL |
a = 1 | {a:1} |
a > 1 | {a:{$gt:1} |
a >= 1 | {a:{$gte:1} |
a < 1 | {a:{$lt:1} |
a <= 1 | {a:{$lte:1} |
a != 1 | {a:{$ne:1} |
a = 1 and b = 1 | {a: 1, b: 1}或{$and: [{a: 1}, {b: 1}]} |
a = 1 or b =1 | {$or: [{a: 1}, {b: 1}]} |
a is null | {a: {$exists: false}} |
a in (1,2,3) | {a: {$in: [1, 2, 3]}} |
a not in (1,2,3) | {a:{$nin:[1,2,3]}} |
a like %xx% | {a:/xx/} |
a like %x | {a:/x$/} |
a like x% | {a:/^x/} |
嵌套查询
db.inventory.insertMany( [ { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" }, { 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" } ]);
整个文档的查询需要整个完档都匹配上包括顺序
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } ) -- 这个可以匹配上 db.inventory.find( { size: { w: 21, h: 14, uom: "cm" } } ) -- 这个不行
网络异常,图片无法展示
|
嵌套字段查询
db.inventory.find( { "size.uom": "in" } ) db.inventory.find( { "size.h": { $lt: 15 } } ) db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )
数组查询
db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] }, { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] }, { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] }, { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] }, { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } ]); db.inventory.find( { tags: ["red", "blank"] } ) db.inventory.find( { tags: { $all: ["red", "blank"] } } ) -- 查询存在red和blank的document
网络异常,图片无法展示
|
查询列表中的元素
db.inventory.find( { tags: "red" } )
查询返回字段
db.inventory.insertMany( [ { item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] }, { item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] }, { item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] }, { item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] }, { item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] } ]); db.inventory.find( { status: "A" } ) -- 返回所有字段 db.inventory.find( { status: "A" }, { item: 1, status: 1 } ) -- 返回_id,item,status 类似SELECT _id, item, status from inventory WHERE status = "A" db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } ) -- 返回item,status db.inventory.find( { status: "A" }, { status: 0, instock: 0 } ) -- 不返回status,instock db.inventory.find( { status: "A" }, { item: 1, status: 1, "size.uom": 1 } ) db.inventory.find( { status: "A" }, { "size.uom": 0 } -- 不返回size.uom其他都返回 ) db.inventory.find( { status: "A" }, { item: 1, status: 1, instock: { $slice: -1 } } ) -- 返回instock最后一个元素
查询NULL数据
db.inventory.insertMany([ { _id: 1, item: null }, { _id: 2 } ]) db.inventory.find( { item: null } ) db.inventory.find( { item : { $type: 10 } } ) db.inventory.find( { item : { $exists: false } } )
BSON TYPE可以看:
网络异常,图片无法展示
|
更新文档
- db.collection.updateOne(,,)
- db.collection.updateMany(,,)
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" } ] ); -- 更新第一条item=paper的数据 db.inventory.updateOne( { item: "paper" }, { $set: { "size.uom": "cm", status: "P" }, $currentDate: { lastModified: true } } ) db.inventory.updateMany( { "qty": { $lt: 50 } }, { $set: { "size.uom": "in", status: "P" }, $currentDate: { lastModified: true } } )
$currentDate将更新lastModified
为最新的时间,如果没有lastModified
将会创建一个
网络异常,图片无法展示
|
删除文档
db.inventory.insertMany( [ { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { 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" }, ] ); db.inventory.deleteMany({}) db.inventory.deleteMany({ status : "A" }) db.inventory.deleteOne( { status: "D" } )
聚合操作
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
管道命令
命令 | 描述 |
$match |
将文档进行分组,统计结果 |
$group |
过滤数据 |
$sort |
文档排序 |
$limit |
限制文档返回数量 |
$skip |
跳过指定文档数量 |
$project |
修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。 |
表达式
命令 | 描述 |
$sum |
计算总和 |
$avg |
计算平均值 |
$min |
获取最小值 |
$max |
获取最大值 |
$push |
在结果⽂档中插⼊值到⼀个数组中 |
$multiply |
将数字相乘并返回结果 |
db.orders.insertMany( [ { _id: 0, name: "Pepperoni", size: "small", price: 19, quantity: 10, date: ISODate( "2021-03-13T08:14:30Z" ) }, { _id: 1, name: "Pepperoni", size: "medium", price: 20, quantity: 20, date : ISODate( "2021-03-13T09:13:24Z" ) }, { _id: 2, name: "Pepperoni", size: "large", price: 21, quantity: 30, date : ISODate( "2021-03-17T09:22:12Z" ) }, { _id: 3, name: "Cheese", size: "small", price: 12, quantity: 15, date : ISODate( "2021-03-13T11:21:39.736Z" ) }, { _id: 4, name: "Cheese", size: "medium", price: 13, quantity:50, date : ISODate( "2022-01-12T21:23:13.331Z" ) }, { _id: 5, name: "Cheese", size: "large", price: 14, quantity: 10, date : ISODate( "2022-01-12T05:08:13Z" ) }, { _id: 6, name: "Vegan", size: "small", price: 17, quantity: 10, date : ISODate( "2021-01-13T05:08:13Z" ) }, { _id: 7, name: "Vegan", size: "medium", price: 18, quantity: 10, date : ISODate( "2021-01-13T05:10:13Z" ) } ] ) db.orders.aggregate({$match:{size:"medium"}}); -- select * from orders where size='medium'; db.orders.aggregate([ { $match:{size:{$in:["small","large"]}} }, { $group:{_id:"$name",total:{$sum:"$quantity"}} } ]); -- select name,sum(quantity) total from orders where size in ('small','large') group by name
网络异常,图片无法展示
|
db.orders.aggregate( [ { $match: { "date": { $gte: new ISODate( "2020-01-30" ), $lt: new ISODate( "2022-01-30" ) } } }, { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, totalOrderValue: { $sum: { $multiply: [ "$price", "$quantity" ] } }, averageOrderQuantity: { $avg: "$quantity" } } }, { $sort: { totalOrderValue: -1 } } ] ); // db.orders.aggregate( { $match:{name:"Vegan"} }, { $project: {_id:0,name:1,date:1} } ); // select name,data from orders where name = 'Vegon';
网络异常,图片无法展示
|
分页查询
db.students.find().skip(10).limit(10)
网络异常,图片无法展示
|