对用户爱好数据做聚合¶
数据模型¶
假定某个运动俱乐部使用了名为 users 的集合,存储了用户入会时间,喜欢的运动等数据,在文档中的格式如下:
{
_id : "jane",
joined : ISODate("2011-03-02"),
likes : ["golf", "racquetball"]
}
{
_id : "joe",
joined : ISODate("2012-07-02"),
likes : ["tennis", "golf", "swimming"]
}
将文档标准化后再排序¶
下面的操作返回按字母顺序排序的大写格式的用户名称记录。该聚合包含了 users 集合中所有文档的用户名。你可能需要预先把用户名标准化,以方便后面步骤的处理。
db.users.aggregate(
[
{ $project : { name:{$toUpper:"$_id"} , _id:0 } },
{ $sort : { name : 1 } }
]
)
users 集合中的所有文档都输入到管道,该管道包含了以下的操作:
本次聚合的结果如下:
{
"name" : "JANE"
},
{
"name" : "JILL"
},
{
"name" : "JOE"
}
查询按入会日期排序的用户名列表¶
接下来的聚合操作将会返回按入会日期排序的用户名列表。这样的聚合可以帮助生成会员的续费通知。
db.users.aggregate(
[
{ $project :
{
month_joined : { $month : "$joined" },
name : "$_id",
_id : 0
}
},
{ $sort : { month_joined : 1 } }
]
)
管道会查询 users 集合中的所有文档,并进行下面这些操作的处理。
执行 $project 操作:
创建两个新的字段: month_joined 和 name 。
从结果集中删除 id 字段。除非明确删除 id 字段,否则 aggregate() 方法默认保留该字段。
$month 操作符从 joined 字段读取到用户的入会月份,并使用 $project 把入会月份赋值到 month_joined 字段。
使用 $sort 操作符对结果集按 month_joined 字段进行排序。
该操作返回的结果集是这样的:
{
"month_joined" : 1,
"name" : "ruth"
},
{
"month_joined" : 1,
"name" : "harold"
},
{
"month_joined" : 1,
"name" : "kate"
}
{
"month_joined" : 2,
"name" : "jill"
}
计算每个月的入会人数¶
下面的操作计算每个月份的入会人数。你可以使用这些数据来制定营销策略和展开会员续费活动。
db.users.aggregate(
[
{ $project : { month_joined : { $month : "$joined" } } } ,
{ $group : { _id : {month_joined:"$month_joined"} , number : { $sum : 1 } } },
{ $sort : { "_id.month_joined" : 1 } }
]
)
管道会查询 users 集合中的所有文档,并进行下面这些操作的处理。
使用 $project 创建一个新的字段 month_joined 。
$month 操作符从 joined 字段读取到用户的入会月份,并使用 $project 把入会月份赋值到 month_joined 字段。
$group 遍历所有文档,并计算每个月份的入会人数。 $group 会为每个月份创建一个新的包含两个字段的新文档:
_id,包含了一个内嵌文档,文档里面记录了 month_joined 字段和它的值。
新加的 number 字段。 $sum 会统计所有当前月份入会的人数,并保存在 number 中。
$sort 会为新创建的文档按 month_joined 字段进行排序。
本次聚合操作的结果是:
{
"_id" : {
"month_joined" : 1
},
"number" : 3
},
{
"_id" : {
"month_joined" : 2
},
"number" : 9
},
{
"_id" : {
"month_joined" : 3
},
"number" : 5
}
查找最受会员喜欢的5种运动¶
下面的操作计算最受会员喜欢的5种运动。这样的分析可以帮助制定未来的发展计划。
db.users.aggregate(
[
{ $unwind : "$likes" },
{ $group : { _id : "$likes" , number : { $sum : 1 } } },
{ $sort : { number : -1 } },
{ $limit : 5 }
]
)
本次管道首先读取 users 中的所有文档,并对这些文档进行下面的操作:
$unwind 首先对 likes 数组中的值进行分类,并为数组的每个值创建一个新的文档。
例子
users 集合中有一些这样的文档
{ _id : "jane", joined : ISODate("2011-03-02"), likes : ["golf", "racquetball"] }
$unwind 会创建出下面的文档:
{ _id : "jane", joined : ISODate("2011-03-02"), likes : "golf" } { _id : "jane", joined : ISODate("2011-03-02"), likes : "racquetball" }
$group 计算每种 likes 的总数。在这个步骤中, $group 会一个创建新的文档:
_id,记录了 likes 值。
number,保存了由 $sum 统计的每种 likes 的总人数值。
$sort 对这些文档按 number 字段进行降序排序。
$limit 限定最前面的5个结果。
本次聚合的结果是 :
{
"_id" : "golf",
"number" : 33
},
{
"_id" : "racquetball",
"number" : 31
},
{
"_id" : "swimming",
"number" : 24
},
{
"_id" : "handball",
"number" : 19
},
{
"_id" : "tennis",
"number" : 18
}