现在,我们有一个集合(数据表),结构及其代码如下:
db.tb5.insert([{"name":"张三","date":"2018/6/1","score":50},
{"name":"李四","date":"2018/6/1","score":57},
{"name":"王五","date":"2018/6/2","score":64},
{"name":"张三","date":"2018/6/3","score":78},
{"name":"王五","date":"2018/6/4","score":77},
{"name":"李四","date":"2018/6/8","score":82}])
结果:
我们现在使用分组操作,来进行数据去重。对name字段进行去重处理。其实,使用distinct()函数也是可以实现的,与分组操作相比不完善。
在DataGrip里面使用distinct()去重,会报如下错,具体原因可能是DataGrip连接MongoDB插件存在问题:
db.tb5.distinct("name")
在MongoDB用distinct()去重,结果如下:
使用分组操作去重,代码及其结果如下:
db.tb5.aggregate([{"$group":{"_id":"$name"}}])//"_id":"$要去重的字段"
结果:
我们可以看见,使用distinct()去重,返回结果是MongoDB的数组类型,而采用分组操作去重,返回结果是3条字符串记录。
接着,我们对数据去重并统计数据的最大值,最小值,求和,平均值。
db.tb5.aggregate([{"$group":{
"_id":"$name",
"max_score":{"$max":"$score"},//设置最大值,从score字段中找出最大值
"min_score":{"$min":"$score"},//设置最小值,从score字段中找出最小值
"avg_score":{"$avg":"$score"},//设置平均值,从score字段中求出平均值
"sum_score":{"$sum":"$score"}//设置求和值,从score字段中求出求和值
}}])
结果:
关于"$sum"的值可使用1,用于统计分组有多少条记录。
db.tb5.aggregate([{"$group":{
"_id":"$name",
"count":{"$sum":1},//设置分组计数,查看分组数
"avg_score":{"$avg":"$score"},//设置平均值,从score中找出平均值
"sum_score":{"$sum":"$score"},//设置求和值,从score中找出求和值
"max_score":{"$max":"$score"},//设置最大值,从score中找出最大值
"min_score":{"$min":"$score"}//设置最小值,从score中找出最小值
}}])
获取最老数据
db.tb5.aggregate([{"$group":{
"_id":"$name",//对name字段去重
"count":{"$sum":1},//统计分组数
"datetime":{"$last":"$date"},//按照最老时间查找时间(date)字段
"score":{"$last":"$score"}//按照最老时间查找分数(score)字段
}}])
获取最新数据
db.tb5.aggregate([{"$group":{
"_id":"$name",
"count":{"$sum":1},//对分组数进行统计
"time":{"$first":"$date"},//获取时间的最新数据
"score":{"$first":"$score"}//获取分数的最新数据
}}])
现在,我们有一张数据表,结构如下:
聚合操作的拆分数组查询,使用$unwind
关键字进行拆分。
db.tb3.aggregate([
{"$unwind":"$岗位"},//将岗位数组拆分
{"$unwind":"$薪资"}//将薪资数组拆分
])
联集合查询(多表查询),
我们先创建集合(数据表),结构如下:
db.tb2.insert([{"id":1,"name":"小红","date":"2018/6/9","age":17,"work":"学生"},
{"id":2,"name":"小明","date":"2018/6/7","age":19,"work":"学生"},
{"id":3,"name":"小光","date":"2018/6/10","age":21,"work":"医生"},
{"id":4,"name":"小芳","date":"2018/6/9","age":22,"work":"服务员"},
{"id":5,"name":"小黑","date":"2018/6/8","age":21,"work":"厨师"},
{"id":6,"name":"小绿","date":"2018/6/9","age":18,"work":"工程师"},
{"id":7,"name":"小蓝","date":"2018/6/9","age":20,"work":"中介"},
{"id":8,"name":"小丽","date":"2018/6/7","age":22,"work":"建筑设计师"}])
再创建集合(数据表),结构如下:
db.tb3.insert([{"user_id":1,"content":"真无聊啊,找不到事情做。","time":"2018/6/11"},
{"user_id":3,"content":"这病症不好治疗啊。","time":"2018/6/12"},
{"user_id":2,"content":"作业真难做啊,唉","time":"2018/6/13"},
{"user_id":4,"content":"现在做什么好呢?。","time":"2018/6/11"},
{"user_id":5,"content":"客人来了,又要做菜了","time":"2018/6/11"},
{"user_id":7,"content":"你好,我是房产中介的小蓝","time":"2018/6/11"},
{"user_id":6,"content":"这材料合格吗?","time":"2018/6/13"},
{"user_id":8,"content":"照着图纸做,别偷懒就行。","time":"2018/6/12"}
])
联集合查询,查询
db.tb3.aggregate(
[
{
"$lookup":{
"from":"tb2",
"localField":"user_id",//localField是当前集合的字段
"foreignField":"id",//foreignField是要查询集合的字段,这两个字段应该是类型和数据相同的。
"as":"user_info"//保存查询结果的字段名。
}
}
]
)
然后,我们再对查询结果的user_info字段做提取。抽取数组user_info里面的嵌入式文档的name字段和work字段。修改代码如下:
db.tb3.aggregate(
[
{
"$lookup":{
"from":"tb2",
"localField":"user_id",//localField是当前集合的字段
"foreignField":"id",//foreignField是要查询集合的字段,这两个字段应该是类型和数据相同的。
"as":"user_info"}},//保存查询结果的字段名。
{"$unwind":"$user_info"},
{"$project":{
"_id":0,//不显示结果
"content":1,//显示结果
"time":1,//显示结果
"name":"$user_info.name",//从嵌入式文档抽取name字段,作为新的name字段
"work":"$user_info.work"//从嵌入式文档抽取work字段,作为新的work字段
}}
]
)
结果:
联集合查询的其他操作基本相同,就先说到这里,大家可以自行学习。
最后,感谢大家前来观看鄙人的文章,文中或有诸多不妥之处,还望指出和海涵。