现在,我们有一个集合(数据表),结构及其代码如下:
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字段 }} ] )
结果:
联集合查询的其他操作基本相同,就先说到这里,大家可以自行学习。
最后,感谢大家前来观看鄙人的文章,文中或有诸多不妥之处,还望指出和海涵。