知识点
1 MongoDB 聚合管道(Aggregation Pipeline)
2 MongoDB Aggregation 管道操作符与表达式
3 数据模拟
4 $project
5 $match
6 $group
7 $sort
8 $limit
9 $skip
10 $lookup 表关联
MongoDB多表关联查询 聚合管道(Aggregation Pipeline)
使用聚合管道可以对集合中的文档进行变换和组合。 实际项目:表关联查询、数据的统计。
MongoDB 中使用 db.COLLECTION_NAME.aggregate([{},…]) 方法 来构建和使用聚合管道。先看下官网给的实例,感受一下聚合管道的用法。
在使用这些命令的时候,感觉,这种命令类似于封装好的, 就好像跟批量修改,批量删除一样,我想这是批量查询
db.orders.aggregate([ {$match:{status:"A"}},{$group:{_id:"$cust_id",total:{$sum:"$amount"}} } ])
MongoDB管道操作符与表达式 Aggregation
SQL 和 NOSQL 对比:
管道表达式:
管道操作符作为“键”,所对应的“值”叫做管道表达式。
例如{match 称为管道操作符,而 status:”A”称为管道表达式,
是管道操作符的操作数(Operand)。
每个管道表达式是一个文档结构,它是由字段名、字段值、和一些表达式操作符组成的。
数据模拟
注意:这里有2张表 order order_item
db.order.insert({"order_id":"1","uid":10,"trade_no":"111","all_price":100,"all_num":2})
db.order.insert({"order_id":"2","uid":7,"trade_no":"222","all_price":90,"all_num":2})
db.order.insert({"order_id":"3","uid":9,"trade_no":"333","all_price":20,"all_num":6})
db.order_item.insert({"order_id":"1","title":"商品鼠标 1","price":50,num:1})
db.order_item.insert({"order_id":"1","title":"商品键盘 2","price":50,num:1})
db.order_item.insert({"order_id":"1","title":"商品键盘 3","price":0,num:1})
db.order_item.insert({"order_id":"2","title":"牛奶","price":50,num:1})
db.order_item.insert({"order_id":"2","title":"酸奶","price":40,num:1})
db.order_item.insert({"order_id":"3","title":"矿泉水","price":2,num:5})
db.order_item.insert({"order_id":"3","title":"毛巾","price":10,num:1})
$project 筛选指定(显示)的字段
修改文档的结构,可以用来重命名 . 增加或删除文档中的字段
db.order.aggregate([
{
$project:{order_id:1,teade_on:1,all_price:1 }
}
])
$match 条件
db.product.aggregate([
{
$lookup:
{
from: "order",
localField: "id_name",
foreignField: "pid",
as: "inventory_docs"
}
}
])
作用:
用于过滤文档,用法类似于 find() 方法中的参数
db.order.aggregate([
{
$project: {
order_id: 1,
teade_on: 1,
all_price: 1
}
},
{
$match: {
all_price: { $gte: 90 }
}
}
])
db.order.aggregate([ {match:{all_price:{$gte:90}}} ])
$group 分组
表示,对数据的分组
将集合中的文档进行分组,可用于统计结果
统计每个订单的订单数量,按照订单号分组
db.order_item.aggregate([ { "order_id", total:{$sum:1}}} ])
db.order_item.aggregate([ { "order_id", total:{price"}}} ])
$sort 排序
对集合表排序 -1 表示倒序显示
这是第一张表 order
db.order.aggregate([
{
match:{
"all_price":{ $sort: {"all_price":-1}}
}
])
$limit 限制
作用,表示 限制 输出几条 可用于分页操作
db.order.aggregate([
{
match:{"all_price":{sort:{"all_price":-1}
},
{
$limit:1
}
])
db.order.aggregate([ {match:{"all_price":{sort:{"all_price":-1}}, {$limit:2} ])
$skip 跳过
跳过第几条数据
db.order.aggregate([ {match:{"all_price":{sort:{"all_price":-1}}, {$skip:1} ])
$lookup 表关联
案列1:
命令:
Order是主表
Order_item是副表
db.order.aggregate([
{
$lookup:
{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
}
])
案列2
命令:
db.order.aggregate([
{
$lookup:
{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
},
{
gte:90
}
])
输出结果:
注意: $project
因为这个 $project 表示 要 显示的字段信息
也可以这样,后面书写排序
分页数据查询倒序案列
exports.getOrder = async (req, res, next) => {
let { pageNo, pageSize } = req.query
const userJson = dealJSON(req.userJson)
let softGetDate = dealJSON(await Busin_game_order.find({ user_id: userJson._id }))
if (softGetDate != '' || softGetDate != null) {
const totalCount = parseInt(softGetDate.length) //获取总数据
const getPage = parseInt(pageNo) - 1 //获取的页数 前端传来的 page =1 mongodb数据库 0为开始 所以要减1
const getSize = parseInt(pageSize) //获取显示多少条 10
const totalPage = parseInt(totalCount / pageSize)
await Busin_game_order.find({ user_id: userJson._id }).skip(getPage * getSize).sort([['create_item',-1]]).limit(getSize).exec((err, data) => {
if (!err) {
return res.send(builder({ pageSize: getSize, pageNo: getPage <= 0 ? 1 : getPage + 1, totalCount: totalCount, totalPage: totalPage <= 0 ? 1 : totalPage, data: dealJSON(data) }))
}
})
} else {
// 返回 10条数据: pageSize 1页:pageNo 总数据200条:totalCount 总页数 10页 :totalPage 具体数据 空
return res.send(builder({ pageSize: getSize, pageNo: getPage, totalCount: totalCount, totalPage: totalPage, data: softGetDate }))
}
}