名词解释
- $addToSet :为组里唯一的值创建一个数组,去除重复的值。
- $push : 返回组内所有值的数组,不去除重复的值。
- tips:集合中的元素必须确保是唯一的,某个给定的值不能在集合中出现两次,通过 $addToSet 可以强制实行,而$push操作没有符没有这个限制,集合中的数据可以不是唯一的。因此,相同的元素可以在$push创建的数组里面多次出现。个人感觉,这里的集合指的不一定是collections或者数据表,而是根据条件筛选出来的一个结果集,根据聚合管道的概念,“聚合里面的每一步输出都将作为下一步的输入。每一步都在输入文档执行单个操作并生成输出文档。”
代码实例
/* 数据表结构如下 */
/* 1 */
{
"_id" : ObjectId("5c84f2819dc6d6412871b1f4"),
"citynum" : 3,
"albumname" : "我们的征途",
"city" : "19",
"channelid" : null,
"albumplaynum" : 19,
"cpid" : "05",
"time" : "20190309",
"payType" : "1",
"albumid" : "983357"
}
/* 2 */
{
"_id" : ObjectId("5c84f2819dc6d6412871b1f5"),
"citynum" : 1,
"albumname" : "我们的征途",
"city" : "22",
"channelid" : null,
"albumplaynum" : 19,
"cpid" : "05",
"time" : "20190309",
"payType" : "1",
"albumid" : "983357"
}
- 要求:根据时间,按照albumid和cpid进行分组,统计citynum的和,展现albumname字段以及citynum的和。
- 使用聚合时,group中分组条件定义了哪些字段,结果集中将只能出现哪些字段,如下所示。
/* 脚本如下 */
db.getCollection('userplay').aggregate([
{
$match:{'time':'20190219'}
},
{
$group:{
_id:{'albumid':'$albumid','cpid':'$cpid'},
sum:{'$sum':'$citynum'},
}
}
])
/* 执行结果 ,更多数据此处省略*/
/* 1 */
{
"_id" : {
"albumid" : "2938",
"cpid" : "01"
},
"sum" : 48
}
/* 2 */
{
"_id" : {
"albumid" : "500003154",
"cpid" : "02"
},
"sum" : 4
}
- 如果想要取得更多的,除分组条件外的字段,就可以使用$addToSet和$push。如下所示,
/* $push */
db.getCollection('userplay').aggregate([
{
$match:{'time':'20190219'}
},
{
$group:{
_id:{'albumid':'$albumid','cpid':'$cpid'},
sum:{'$sum':'$citynum'},
albumname:{$push:'$albumname'},
}
}
])
/* 结果如下 */
/* 1 */
{
"_id" : {
"albumid" : "2938",
"cpid" : "01"
},
"sum" : 48,
"albumname" : [
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞",
"小胖妞"
]
}
/* 2 */
{
"_id" : {
"albumid" : "500003154",
"cpid" : "02"
},
"sum" : 4,
"albumname" : [
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 ",
"我是大熊猫 "
]
}
显然不是我想要的结果,因为albumname字段的值重复了,而我只要一个值。
根据文档中写到的“集合中的元素必须确保是唯一的,某个给定的值不能在集合中出现两次,通过 $addToSet 可以强制实行,而$push操作没有符没有这个限制,集合中的数据可以不是唯一的。因此,相同的元素可以在$push创建的数组里面多次出现。”
将$push修改为$addToSet再次执行。
/* 执行脚本 */
db.getCollection('userplay').aggregate([
{
$match:{'time':'20190219'}
},
{
$group:{
_id:{'albumid':'$albumid','cpid':'$cpid'},
sum:{'$sum':'$citynum'},
albumname:{$addToSet:'$albumname'},
}
}
])
/* 结果如下 */
/* 1 */
{
"_id" : {
"albumid" : "2938",
"cpid" : "01"
},
"sum" : 48,
"albumname" : [
"小胖妞"
]
}
/* 2 */
{
"_id" : {
"albumid" : "500003154",
"cpid" : "02"
},
"sum" : 4,
"albumname" : [
"我是大熊猫 "
]
}
/* 3 */
{
"_id" : {
"albumid" : "795985",
"cpid" : "02"
},
"sum" : 48,
"albumname" : [
"黑夜传说Ⅳ:觉醒.3D(片段)"
]
}
OK,达到想要的效果,之前项目中遇到了类似的问题,查看文档时看到了解决方法,记录一下。
好记性不如一篇好笔记!
网友评论