mongo聚合(aggregate)操作,相比于固定好的find、update等基本操作方法,是相当于其底层操作,可以使用聚合操作执行更为复杂的操作
常用管道符
常用管道 | 含义 |
---|---|
$group | 将collection中的document分组,可用于统计结果 |
$match | 过滤数据,只输出符合结果的文档 |
$project | 修改输入文档的结构(例如重命名,增加、删除字段,创建结算结果等) |
$sort | 将结果进行排序后输出 |
$limit | 限制管道输出的结果个数 |
$skip | 跳过制定数量的结果,并且返回剩下的结果 |
$addFieIds | 添加字段字段 |
$lookup | 关联数据 |
$unwind | 将数组类型的字段进行拆分 |
表达式操作符
常用表达式 | 含义 |
---|---|
$sum | 计算总和,{$sum: 1}表示返回总和×1的值(即总和的数量),使用{$sum: '$制定字段'}也能直接获取制定字段的值的总和 | |
$avg | 平均值 |
$min | min |
$max | max |
$push | 将结果文档中插入值到一个数组中 |
$first | 根据文档的排序获取第一个文档数据 |
$last | 同理,获取最后一个数据 |
aggregate操作规范
使用时的基本方法
db.user.aggregate([...操作])
aggregate第一个参数是数组,数组中嵌套单个操作的对象;
例如:查询user表中,name为tom的数据
db.user.aggregate([{
$match: {
name: "tom"
}
}])
管道符操作实操
$group分组
分组一般与计数查询一起使用
示例:按年龄分组并查询各年龄人数
- _id:必填,分组字段,值可以为null,当为null时,无分组
在之上的语句中,$group._id字段值为要分组的字段,且字段需以$进行引用;db.user.aggregate([{ $group: { _id:"$age", count:{$sum:1} } }])
如果$group._id值为null或空字符传,则会返回当前表所有数据的个数
$match 查询
过滤数据,只输出符合结果的文档
示例:查询年龄大于等于10且小于等于20的人
db.user.aggregate([{
$match: {
//基础的查询操作格式
age: {
$gte: 10,$lte: 20
}
}
}])
$project字段展示
修改输入文档的结构(例如重命名,增加、删除字段,创建结算结果等)
其实更多的实际应用时,都是作为修改输出字段、限定展示字段(类似元select)
db.user.aggregate([
{
$project: {
name: 1,
age: 1,
"renameAge": "$age"
}
}
])
$sort排序
与原生排序一样,参数取值为key-value,value为1是正序,为0是倒叙
db.user.aggregate([
{
$project: {
name: 1,
age: 1,
"renameAge": "$age"
}
},
{
$sort: {
age: 1
}
}
])
$limit展示
展示条数
db.user.aggregate([
{
$sort: {
age: 1
}
},
{
$limit: 1
}
])
$skip跳过
db.user.aggregate([
{
$sort: {
age: 1
}
},
{
$skip: 1
},
{
$limit: 1
}
])
$addFieIds 添加字段
db.user.aggregate([
{
"$addFields": {
"name1": "$name"
}
},
{
$project: {
"name": 1,
"name1": 1
}
}
])
$lookup关联表
关联表,
- from:同一数据库下等待被关联的表
- localField:源表中的关联字段
- foreignField:form的表中与源表的关联字段
- as:输出为某个字段,如果该字段已存在,则关联结果会覆盖原值
```javascript
db.user.aggregate([
{
}$lookup: { from: "organ", localField: "organ_id", foreignField: "_id", as: "organazition" }
])
![image.png](https://cdn.nlark.com/yuque/0/2022/png/21500184/1657783511997-be850824-1dbc-42f2-89c5-606588646a19.png#clientId=u0343c132-cdf7-4&from=paste&height=272&id=u8e851119&originHeight=544&originWidth=2286&originalType=binary&ratio=1&rotation=0&showTitle=false&size=130887&status=done&style=none&taskId=u635130f3-61c5-4091-a51d-8bcef84c609&title=&width=1143)
<a name="tEnmF"></a>
## $unwind数组类型的字段进行拆分
```javascript
db.user.aggregate([
{
$match: {
_id: ObjectId("6247f55d9dce52289328d993")
}
},
{
$unwind: "$address"
}
])
部分实现场景
分组计数
按年龄分组,并计数每个年龄的人数
db.user.aggregate([
{
$group: {
_id: "$age",
"count": {
$sum: 1
}
}
}
])
按年龄分组,并计数年龄大于18的人数
db.user.aggregate([
{
$match: {
age: {
$gt: 18
}
}
},
{
$group: {
_id: "$age",
"count": {
$sum: 1
}
}
}
])
将时间格式转化为字符串
db.user.aggregate([
{
"$addFields": {
"timestamp": {
"$toLong": "$create_time"
}
}
},
{
$project: {
name: 1,
time: {
$dateToString: {
format: "%Y-%m-%d %H:%M:%S",
date: {
"$add": [new Date(0), "$timestamp", 28800000]
}
}
}
}
},
{
$sort: {
time: 1
}
}
])
- [ ]