[英]Grouping objects inside an array - MongoDB Aggregation
I am using a training grades database from MongoDB.我正在使用来自 MongoDB 的培训成绩数据库。 It is structured as follows.
它的结构如下。
"_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"
}
}
I am trying to run aggregation which returns all documents grouped first by class_id and then by student_id with all homework scores like the following.我正在尝试运行聚合,它返回首先按 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
},
]
},
]
}
I am running the following aggregation function.我正在运行以下聚合函数。
[
{
'$unwind': {
'path': '$scores'
}
}, {
'$match': {
'scores.type': 'homework'
}
}, {
'$group': {
'_id': '$class_id',
'scores': {
'$push': {
'type': '$scores.type',
'score': '$scores.score',
'student_id': '$student_id'
}
}
}
}
]
But it is returning the following result:但它返回以下结果:
{
_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
},
]
}
If even if there are multiple objects in the scores array, it is not combining them with the student_id group and shows them separate.如果即使scores数组中有多个对象,也不会将它们与student_id组合并,而是将它们分开显示。 I am not sure of what I should add to the aggregation.
我不确定我应该在聚合中添加什么。 Any help would be appreciated!
任何帮助,将不胜感激!
Try With this Aggregate Query,尝试使用此聚合查询,
[
{
'$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'
}
}
}
}
]
Mongo Playground Link Mongo游乐场链接
I think this is the precise format you wanted.我认为这是您想要的精确格式。
The aggregation pipeline:聚合管道:
[
{
"$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"
}
}
]
The first two stages of the pipeline I guess are simply to filter out the non-homework documents.我猜管道的前两个阶段只是过滤掉非作业文档。
To perform a "nested grouping" of sorts, where not only does the data have an outer grouping over class_id
but an inner grouping in the scores
over student_id
, first we group the data in the first $group
stage over both those fields, much like described here .要执行各种“嵌套分组”,其中不仅数据在
class_id
有外部分组,而且在student_id
上的scores
有内部分组,首先我们在这两个字段的第一个$group
阶段对数据进行$group
,很像在这里描述。
The scores
array in each document here will be the same as the arrays we need in each inner grouping (over student_id
), so, now we can just group by the class_name
(in the _id
object after the result of the first group stage) and add the student_id
along with the scores
in each object to push in the all_scores
array.此处每个文档中的
scores
数组将与我们在每个内部分组(通过student_id
)中所需的数组相同,因此,现在我们只需按class_name
分组(在第一个小组阶段结果之后的_id
对象中)和添加student_id
以及每个对象中的scores
以推入all_scores
数组。 Then the final $project
stage is pretty trivial, just to get it in the format that we want.然后最后的
$project
阶段就很简单了,只是把它变成我们想要的格式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.