5a0*_*01P 5 mongodb mongodb-query aggregation-framework
我在 MongoDB 中有一组元素,如下所示:
/* 1 */
{
"_id" : ObjectId("58736c7f7d43c305461cdb9b"),
"Name" : "Kevin",
"pb_event" : [
{
"event_type" : "Birthday",
"event_date" : "2014-08-31"
},
{
"event_type" : "Anniversary",
"event_date" : "2014-08-31"
}
]
}
/* 2 */
{
"_id" : ObjectId("58736cfc7d43c305461cdba8"),
"Name" : "Peter",
"pb_event" : [
{
"event_type" : "Birthday",
"event_date" : "2014-08-31"
},
{
"event_type" : "Anniversary",
"event_date" : "2015-03-24"
}
]
}
/* 3 */
{
"_id" : ObjectId("58736cfc7d43c305461cdba9"),
"Name" : "Pole",
"pb_event" : [
{
"event_type" : "Birthday",
"event_date" : "2015-03-24"
},
{
"event_type" : "Work Anniversary",
"event_date" : "2015-03-24"
}
]
}
Run Code Online (Sandbox Code Playgroud)
现在我想要的结果是 group on event_date
then after group on event_type
。event_type
包含相关用户的所有名称,然后是相应数组中的记录数。
预期输出
/* 1 */
{
"event_date" : "2014-08-31",
"data" : [
{
"event_type" : "Birthday",
"details" : [
{
"_id" : ObjectId("58736c7f7d43c305461cdb9b"),
"name" : "Kevin"
},
{
"_id" : ObjectId("58736cfc7d43c305461cdba8"),
"name" : "Peter"
}
],
"count" : 2
},
{
"event_type" : "Anniversary",
"details" : [
{
"_id" : ObjectId("58736c7f7d43c305461cdb9b"),
"name" : "Kevin"
}
],
"count" : 1
}
]
}
/* 2 */
{
"event_date" : "2015-03-24",
"data" : [
{
"event_type" : "Anniversary",
"details" : [
{
"_id" : ObjectId("58736cfc7d43c305461cdba8"),
"name" : "Peter"
}
],
"count" : 1
},
{
"event_type" : "Birthday",
"details" : [
{
"_id" : ObjectId("58736cfc7d43c305461cdba9"),
"name" : "Pole"
}
],
"count" : 1
},
{
"event_type" : "Work Anniversary",
"details" : [
{
"_id" : ObjectId("58736cfc7d43c305461cdba9"),
"name" : "Pole"
}
],
"count" : 1
}
]
}
Run Code Online (Sandbox Code Playgroud)
使用聚合框架,您需要运行具有以下阶段的管道,以便获得所需的结果:
db.collection.aggregate([
{ "$unwind": "$pb_event" },
{
"$group": {
"_id": {
"event_date": "$pb_event.event_date",
"event_type": "$pb_event.event_type"
},
"details": {
"$push": {
"_id": "$_id",
"name": "$Name"
}
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.event_date",
"data": {
"$push": {
"event_type": "$_id.event_type",
"details": "$details",
"count": "$count"
}
}
}
},
{
"$project": {
"_id": 0,
"event_date": "$_id",
"data": 1
}
}
])
Run Code Online (Sandbox Code Playgroud)
在上面的管道中,第一步是$unwind
运算符
{ "$unwind": "$pb_event" }
Run Code Online (Sandbox Code Playgroud)
当数据存储为数组时,这非常方便。当展开运算符应用于列表数据字段时,它将为应用展开的列表数据字段的每个元素生成一条新记录。它基本上使数据扁平化。
这是下一个管道阶段的必要操作,在该阶段中,您将通过解构的数组字段$group
对展平文档进行分组,并且:pb_event
event_date
event_type
{
"$group": {
"_id": {
"event_date": "$pb_event.event_date",
"event_type": "$pb_event.event_type"
},
"details": {
"$push": {
"_id": "$_id",
"name": "$Name"
}
},
"count": { "$sum": 1 }
}
},
Run Code Online (Sandbox Code Playgroud)
管道$group
运算符类似于 SQL 的GROUP BY
子句。GROUP BY
在 SQL 中,除非使用任何聚合函数,否则无法使用。同样,您也必须使用 MongoDB 中的聚合函数(称为累加器运算符)。您可以在此处阅读有关聚合函数的更多信息。
在此$group
操作中,逻辑使用累加器运算符计算计数聚合,即组中文档的总数$sum
。在同一管道中,您可以使用为每个组返回表达式值数组的运算符来聚合name
和子文档的列表。_id
$push
前面的$group
管道
{
"$group": {
"_id": "$_id.event_date",
"data": {
"$push": {
"event_type": "$_id.event_type",
"details": "$details",
"count": "$count"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
将通过分组进一步聚合来自最后一个管道的结果,这通过使用最后的管道阶段event_date
创建新的数据列表来形成所需输出的基础$push
$project
{
"$project": {
"_id": 0,
"event_date": "$_id",
"data": 1
}
}
Run Code Online (Sandbox Code Playgroud)
通过将字段重命名_id
为event_date
并保留另一个字段来重塑文档字段。
归档时间: |
|
查看次数: |
3427 次 |
最近记录: |