使用用户偏好数据进行聚合
数据模型
考虑一个包含 members
集合的体育俱乐部数据库,该集合跟踪成员姓名、加入日期和运动偏好:
db.members.insertMany( [ { _id: "jane", joined: ISODate("2011-03-02"), likes: ["golf", "racquetball"] }, { _id: "joe", joined: ISODate("2012-07-02"), likes: ["tennis", "golf", "swimming"] }, { _id: "ruth", joined: ISODate("2012-01-14"), likes: ["golf", "racquetball"] }, { _id: "harold", joined: ISODate("2012-01-21"), likes: ["handball", "golf", "racquetball"] }, { _id: "kate", joined: ISODate("2012-01-14"), likes: ["swimming", "tennis"] } ] )
返回单个字段
以下操作使用 $project
仅返回members
集合中所有文档的_id
字段:
db.members.aggregate( [ { $project: { _id: 1 } } ] )
该操作将返回以下文档:
[ { _id: 'jane' }, { _id: 'joe' }, { _id: 'ruth' }, { _id: 'harold' }, { _id: 'kate' } ]
对于基本查询和投影操作,使用find()
方法的标准查询具有最佳性能。
规范化和排序文档
以下操作按字母顺序返回大写的成员名称。 您可以执行此操作以使成员名称规范化以进行处理。
db.members.aggregate( [ { $project: { name: { $toUpper: "$_id" }, _id: 0 } }, { $sort: { name: 1 } } ] )
members
集合中的所有文档都会通过管道,该管道包含以下操作:
操作返回以下结果:
[ { name: 'HAROLD' }, { name: 'JANE' }, { name: 'JOE' }, { name: 'KATE' }, { name: 'RUTH' } ]
返回按加入月份排序的用户名
以下聚合操作返回按加入月份排序的成员名称。 您可以使用此聚合来帮助生成成员资格续订通知。
db.members.aggregate( [ { $project: { month_joined: { $month: "$joined" }, name: "$_id", _id: 0 } }, { $sort: { month_joined: 1 } } ] )
管道通过以下操作传递 members
集合中的所有文档:
$project
操作符:创建两个新字段:
month_joined
和name
。从结果中抑制
id
。除非显式取消,否则aggregate()
方法包括_id
。
$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: 3, name: 'jane' }, { month_joined: 7, name: 'joe' } ]
返回每月的连接总数
以下操作显示了一年中每个月的加入人数。您可以使用这些汇总数据来制定招聘和市场营销策略。
db.members.aggregate( [ { $project: { month_joined: { $month: "$joined" } } } , { $group: { _id: { month_joined: "$month_joined" } , number: { $sum: 1 } } }, { $sort: { "_id.month_joined": 1 } } ] )
管道通过以下操作传递 members
集合中的所有文档:
$project
操作符创建一个名为month_joined
的新字段。$month
操作符将joined
字段的值转换为月份的整数表示形式。然后,$project
操作符将这些值分配给month_joined
字段。$group
操作符收集具有给定month_joined
值的所有文档,并计算具有该值的文档数量。具体来说,对于每个唯一值,$group
都会创建包含两个字段的新“每月”文档:_id
,它包含一个带有month_joined
字段及其值的嵌套文档。number
,这是一个生成字段。对于每个包含给定month_joined
值的文档,$sum
操作符将此字段递增 1。
聚合操作返回以下文档:
[ { _id: { month_joined: 1 }, number: 3 }, { _id: { month_joined: 3 }, number: 1 }, { _id: { month_joined: 7 }, number: 1 } ]
返回五个最常见的“Likes”
以下聚合收集了数据集最“喜欢”的前五个活动。 此类分析有助于为规划和未来发展提供信息。
db.members.aggregate( [ { $unwind: "$likes" }, { $group: { _id: "$likes" , number: { $sum: 1 } } }, { $sort: { number: -1 } }, { $limit: 5 } ] )
该管道从 members
集合中的所有文档开始,并通过以下操作传递这些文档:
$unwind
操作符分隔likes
数组中的每个值,并为数组中的每个元素创建源文档的新版本。例子
以
members
集合中的以下文档为例:{ _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
,这是一个生成字段。对于每个包含给定likes
值的文档,$sum
操作符将此字段递增 1。
$sort
操作符按number
字段以相反的顺序对这些文档进行排序。$limit
操作符只包含前 5 个结果文档。
聚合操作返回以下文档:
[ { _id: 'golf', number: 4 }, { _id: 'racquetball', number: 3 }, { _id: 'tennis', number: 2 }, { _id: 'swimming', number: 2 }, { _id: 'handball', number: 1 } ]