我想找到"studentId"
的计数,其中"classId"
为"cls12sc"
而"subjectId"
为"19690112"
且此"subjectId"
每次使用都不同聚合。此处"classId"
会动态传递,"classId"
我需要获得与"subjectId"
相关联的"classId"
点数与"subjectId"
和"sScore"
条件匹配。
这是我的收藏(学生)Json数据:
架构:
{
"_id" : ObjectId("53f63fc8f2b643f6ebb8a1a9"),
"subjectId" : 19690112,
"studentId" : "ads5ad2",
"sScore" : 25
},
{
"_id" : ObjectId("53f63fc8f2b643f6ebb8a1a2"),
"subjectId" : 19690112,
"studentId" : "s5sdf45",
"sScore" : 85
},
{
"_id" : ObjectId("53f63fc8f2b643f6ebb8a902"),
"subjectId" : 19690112,
"classId" : "cls12sc",
"sScore" : 64
}
,请参阅此附加图片
这是我的聚合管道:
var classId = "cls12sc" ;
var subjectId = "19690112";
db.Students.aggregate([
{$match:{"classId" : classId, "subjectId": subjectId }},
{$group:{"_id" : "$subjectId", count: { $sum: 1 }}}
]);
但我不想在同一个集合中两次使用var声明。我想只传递classId
。从classId
开始,它应该获取subjectId
并获得计数。
查看可能的收集数据并输出可能性:
{
"_id" : ObjectId("53f63fc8f2b643f6ebb8a1a9"),
"subjectId" : 19690112,
"studentId" : "ads5ad2",
"sScore" : 25
},
{
"_id" : ObjectId("53f63fc8f2b643f6ebb8a1a2"),
"subjectId" : 19690112,
"studentId" : "s5sdf45",
"sScore" : 85
},
{
"_id" : ObjectId("53f63fc8f2b643f6ebb8a902"),
"subjectId" : 19690112,
"classId" : "cls12sc",
"sScore" : 64
}
{
"_id" : ObjectId("53Ro6GpGjJTeam2JxfN"),
"subjectId" : "567818ec20a3d410709bb202",
"studentId" : "kobo2WfCpN7RHMxi7",
"sScore" : 89
}
{
"_id" : ObjectId("53badBbn9dnv88qXdrT"),
"subjectId" : "567818ec20a3d410709bb202",
"studentId" : "AYQ48otoD345ZWAumnMD",
"sScore" : 8
}
{
"_id" : ObjectId("53pLhmMajApQDDzhonf"),
"subjectId" : "567818ec20a3d410709bb202",
"studentId" : "czASSwXvaeRA2ZXfp",
"sScore" : "12"
}
{
"_id" : ObjectId("53g4tCFQFhobasRCkTy"),
"subjectId" : "567818ec20a3d410709bb202",
"classId" : "AYQ48otoDZWAumnMD",
"sScore" : 77
}
{
"_id" : ObjectId("53TkCfKE29ZCsXJv7CZ"),
"subjectId" : "567814d620a3d410709b91ba",
"studentId" : "5yJdSrdrLKt9DDQRW",
"sScore" : 20
}
{
"_id" : ObjectId("538JruGLRnMDaE4gyc3"),
"subjectId" : "567814d620a3d410709b91ba",
"classId" : "5yJdSrdrLKt9DDQRW",
"sScore" : 66
}
{
"_id" : ObjectId("533Qu3zt5suR8ymkRJ6"),
"subjectId" : "567814d620a3d410709b91ba",
"studentId" : "AYQ48ot234h4oDZWAumnMD",
"sScore" : 99
}
input
if classId == "5yJdSrdrLKt9DDQRW" and "sScore" == 99
then
output : 3
input
if classId == "AYQ48otoDZWAumnMD" and "sScore" == 99
then
output : 4
有人可以帮我吗?
答案 0 :(得分:0)
运行以下管道以获得所需的结果:
var classId = "AYQ48otoDZWAumnMD";
db.Students.aggregate([
{
"$group": {
"_id": "$subjectId",
"classId": {
"$max": {
"$cond": [
{ "$gt": ["$classId", null] },
"$classId", null
]
}
},
"count": { "$sum": 1 }
}
},
{ "$match": { "classId": classId } }
])
示例输出
{
"_id" : "567818ec20a3d410709bb202",
"classId" : "AYQ48otoDZWAumnMD",
"count" : 4
}
在上面的 $group
管道中,您需要按subjectId
键对所有文档进行分组,但在管道的下方需要classId
密钥您要按以下方式过滤分组的文档。由于某些文档没有classId
字段,因此您需要一种机制,使用$group
在 available accumulators 管道中创建此字段。所以一个好的黑客就是使用 $max
运算符返回现有的classId字段或占位符null值,全部通过 $cond
tenary运算符,使用BSON Types Comparison Order来评估字段的存在。