将数组中的对象分组-MongoDB聚合



我使用的是MongoDB中的培训成绩数据库。其结构如下。

"_id": {
"$oid": "56d5f7eb604eb380b0d8d8fa"
},
"class_id": {
"$numberDouble": "173"
},
"scores": [
{
"score": {
"$numberDouble": "19.81430597438296"
},
"type": "exam"
},
{
"score": {
"$numberDouble": "16.851404299968642"
},
"type": "quiz"
},
{
"score": {
"$numberDouble": "60.108751761488186"
},
"type": "homework"
},
{
"score": {
"$numberDouble": "22.886167083915776"
},
"type": "homework"
}
],
"student_id": {
"$numberDouble": "4"
}
}

我正在尝试运行聚合,它返回所有文档,这些文档首先按class_id分组,然后按student_id分组。

{
class_id: 3,
all_scores: [
{
student_id: 110, 
scores : [
{
type: "homework", 
score: 89.98
},
{
type: "homework", 
score: 90.98
},
]
},
{
student_id:190, 
scores : [
{
type: "homework", 
score: 18.98
},
{
type: "homework", 
score: 99.98
},
]
},
]
}

我正在运行以下聚合函数。

[
{
'$unwind': {
'path': '$scores'
}
}, {
'$match': {
'scores.type': 'homework'
}
}, {
'$group': {
'_id': '$class_id', 
'scores': {
'$push': {
'type': '$scores.type', 
'score': '$scores.score', 
'student_id': '$student_id'
}
}
}
}
]

但它返回以下结果:

{
_id: 3, 
scores: [
{
"type": "homework",
"score": 89.98, 
"student_id": 110
}, 
{
"type": "homework",
"score": 90.98, 
"student_id": 110
}, 
{
"type": "homework",
"score": 18.98, 
"student_id": 190
}, 
{
"type": "homework",
"score": 99.98, 
"student_id": 190
},
]
}

如果即使分数数组中有多个对象,它也不会将它们与student_id组组合,而是将它们单独显示。我不确定应该在聚合中添加什么。任何帮助都将不胜感激!

Mongo游乐场链接

我想这正是你想要的格式。

聚合管道:

[
{
"$unwind": {
"path": "$scores"
}
},
{
"$match": {
"scores.type": "homework"
}
},
{
"$group": {
"_id": {
"class_id": "$class_id",
"student_id": "$student_id"
},
"scores": {
"$push": {
"type": "$scores.type",
"score": "$scores.score"
}
}
}
},
{
$group: {
_id: "$_id.class_id",
all_scores: {
$push: {
"student_id": "$_id.student_id",
scores: "$scores"
}
}
}
},
{
"$project": {
_id: 0,
class_id: "$_id",
all_scores: "$all_scores"
}
}
]

我想,管道的前两个阶段只是过滤掉非家庭作业文档。

为了执行";嵌套分组";当然,其中数据不仅在class_id上具有外部分组,而且在scores中在student_id上具有内部分组,首先我们将第一个$group阶段中的数据分组在这两个字段上,非常像这里所描述的。

这里的每个文档中的scores数组将与我们在每个内部分组中所需的数组相同(在student_id上(,因此,现在我们只需按class_name分组(在第一个分组阶段的结果之后的_id对象中(,并将student_id与每个对象中的scores一起添加到all_scores数组中。那么最后的$project阶段是非常琐碎的,只是为了获得我们想要的格式。

尝试使用此聚合查询,

[
{
'$unwind': {
'path': '$scores'
}
}, {
'$match': {
'scores.type': 'homework'
}
}, {
'$group': {
'_id': {class_id:'$class_id',
student_id:'$student_id'}, 
'scores': {
'$push': {
'type': '$scores.type', 
'score': '$scores.score'
}
}
}
}
]

最新更新