Docs 菜单

Docs 主页开发应用程序MongoDB Manual

使用用户偏好数据进行聚合

在此页面上

  • 数据模型
  • 规范化和排序文档

假设一家体育俱乐部的数据库包含一个 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 集合中的所有文档都会通过管道,该管道包含以下操作:

  • $project 操作符:

    • 创建一个名为 name 的新字段。

    • 使用 $toUpper 操作符将 _id 的值转换为大写。然后,$project 创建一个名为 name 的新字段来保存此值。

    • 取消 id 字段。$project 将默认传递 _id 字段,除非显式取消。

  • $sort 操作符按 name 字段对结果进行排序。

聚合结果类似于以下内容:

{
"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_joinedname

    • 从结果中抑制 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" : 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 操作符收集具有给定 month_joined 值的所有文档,并计算具有该值的文档数量。具体来说,对于每个唯一值,$group 都会创建包含两个字段的新“每月”文档:

    • _id,它包含一个带有 month_joined 字段及其值的嵌套文档。

    • number,这是一个生成字段。对于每个包含给定 month_joined 值的文档,$sum 操作符将此字段递增 1。

  • $sort 操作符根据 month_joined 字段的内容对 $group 创建的文档进行排序。

此聚合操作的结果类似于以下内容:

{
"_id" : {
"month_joined" : 1
},
"number" : 3
},
{
"_id" : {
"month_joined" : 2
},
"number" : 9
},
{
"_id" : {
"month_joined" : 3
},
"number" : 5
}

返回五个最常见的“Likes”

以下聚合收集了数据集中最“喜欢”的前五个活动。这类分析有助于为规划和未来发展提供信息。

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,这是一个生成字段。对于每个包含给定 likes 值的文档,$sum 操作符将此字段递增 1。

  • $sort 操作符按 number 字段以相反的顺序对这些文档进行排序。

  • $limit 操作符只包含前 5 个结果文档。

聚合结果如下:

{
"_id" : "golf",
"number" : 33
},
{
"_id" : "racquetball",
"number" : 31
},
{
"_id" : "swimming",
"number" : 24
},
{
"_id" : "handball",
"number" : 19
},
{
"_id" : "tennis",
"number" : 18
}
← 与邮政编码数据集的聚合