MongoDB数据库高级操作之聚合aggregate

1. 基本语法

db.collection_name.aggregat([{管道:{表达式}}])

2. MongoDB管道

作用: 文档处理完毕,通过管道进入下一次处理

常见管道:

  1. $group: 分组
  2. $match: 筛选
  3. $project: 投影
  4. $limit: 显示指定数量文档
  5. $skip: 跳过一定数量的文档
  6. $unwind:将某个文档中的数组字段拆分成多条, 其中每条包含数值中的一个值

常见表达式:

  1. $sum: 求和
  2. $avg: 求平均值
  3. $min:最小值
  4. $max: 最大值
  5. $push: 在结果文档中插入值到一个数组中
  6. $first: 取结果文档中的第一个
  7. $last: 取结果文档中的最后一个

3. 数据准备

# documents
/* 1 */
{
    "_id" : ObjectId("5b59847d4871a34e5ff43c34"),
    "name" : "hah"
}

/* 2 */
{
    "_id" : ObjectId("5b5984944871a34e5ff43c35"),
    "name" : "all",
    "age" : 18.0
}

/* 3 */
{
    "_id" : ObjectId("5b5984a34871a34e5ff43c36"),
    "name" : "change",
    "age" : 10.0
}

/* 4 */
{
    "_id" : ObjectId("5b5984b34871a34e5ff43c37"),
    "name" : "go",
    "age" : 11.0
}

/* 5 */
{
    "_id" : ObjectId("5b598ef04871a34e5ff43c38"),
    "name" : "johansson",
    "age" : 17.0
}

/* 6 */
{
    "_id" : ObjectId("5b598f024871a34e5ff43c39"),
    "name" : "xiaoai",
    "age" : 23.0
}

/* 7 */
{
    "_id" : ObjectId("5b5991214871a34e5ff43c3a"),
    "name" : "match",
    "gender" : false,
    "age" : 22.0
}

/* 8 */
{
    "_id" : ObjectId("5b59914d4871a34e5ff43c3b"),
    "name" : "project",
    "gender" : true,
    "age" : 24.0
}

/* 9 */
{
    "_id" : ObjectId("5b5991694871a34e5ff43c3c"),
    "name" : "sort",
    "gender" : true,
    "age" : 25.0
}

/* 10 */
{
    "_id" : ObjectId("5b5991804871a34e5ff43c3d"),
    "name" : "limit",
    "gender" : false,
    "age" : 18.0
}

/* 11 */
{
    "_id" : ObjectId("5b59919a4871a34e5ff43c3e"),
    "name" : "skip",
    "gender" : true,
    "age" : 19.0
}

/* 12 */
{
    "_id" : ObjectId("5b5991b84871a34e5ff43c3f"),
    "name" : "unwind",
    "gender" : false,
    "age" : 30.0
}

/* 13 */
{
    "_id" : ObjectId("5b599bf54871a34e5ff43c40"),
    "name" : "ye",
    "title" : "costume",
    "size" : [ 
        "s", 
        "m", 
        "l", 
        "xl", 
        "xxl"
    ]
}

4. 操作

# 分组$group
db.sub.aggregate([
{$group:{_id:"null, counter:{$sum:1}, avg:{$avg:"$age"}}}
])
	_id:null  --- 表示把文档分为一组
	counter:{$sum:1} --- 统计一组数据中的document
	avg:{$avg:"$age"} --- 对每组数据中age字段求平均值


db.sub.aggregate([
{$group:{_id:"$gender", counter:{$sum:1}, avg:{$avg:"$age"}, name:{$push:"$name"}}}
])

	表达式$push: 返回一个list  把该组中每个document的字段追加到一个列表/数组中
				其中$$ROOT 表示把该组中的每个document追加到列表/数组中

# 查询年龄大于20的document
# 筛选$match
db.sub.aggregate([
{$match: {age:{$gt:20}}}
])

# 查询年龄大于20  且 按gender分组 统计各组的数目
db.sub.aggregate([
{$match: {age:{$gt:20}}},
{$group:{_id:"$gender", counter:{$sum:1}}}
])

# 查询年龄大于20  且 按gender分组 统计各组的数目  且 只显示counter字段
# 投影$project
db.sub.aggregate([
{$match: {age:{$gt:20}}},   # 筛选
{$group:{_id:"$gender", counter:{$sum:1}}},  # 分组
{$project:{_id:0,counter:1}}  # 投影
])

# 按照_id字段升序排序
# 排序$sort
db.sub.aggregate([
{$match: {age:{$gt:20}}},   
{$group:{_id:"$gender", counter:{$sum:1}}},  
{$project:{_id:1,counter:1}},
{$sort:{_id:1}}
])

# 跳过$skip  只显示$limit
db.sub.aggregate([
{$match: {age:{$gt:20}}},   
{$group:{_id:"$gender", counter:{$sum:1}}},  
{$project:{_id:1,counter:1}},
{$sort:{_id:1}},
{$skip:1},
{$limit:2},
])


# 拆分$unwind --- 将文档只给你的某一个数组字段拆分成多条,每条包含数组中的一个值
# 对某个字段值进行拆分
db.sub.aggregate([
{$unwind:{path:"$size"}}
])
# 对某个字段值进行拆分
# 处理空数组, 非数组, 无字段,null 的情况
db.sub.aggregate([
{$unwind:{path:"$size", preserveNullAndEmptyArrays:true}}
])

 

你可能感兴趣的:(DataBase)