我通过 $regex 使用 $lookup 聚合了阶段。在此代码中:
我有团体和学生收藏。
Groups: {_id : ObjectId, title: String}
Students{mainGroups: String,isReserved: Boolean}
mainGroups 是一个连接字符串,对于所有组,每个学生都在学校参加过。
我的代码为我提供了所有组的所有学生集合,无论有多少学生都被返回。
[
{
$addFields: {
gid: { $toString: "$_id" }
}
},
{
$lookup: {
from: 'students',
let: { groupId: "$gid" },
pipeline: [
{
$match: {
$expr: {
$regexMatch: {
input: "$mainGroups",
regex: { $concat: [".*", "$$groupId", ".*"] },
options: "i"
}
}
}
}
],
as: "students"
}
},
{
$project: {
_id: 1,
gid: 1,
title: 1,
studentCount: { $size: "$students" }
}
}
]
我想通过学生集合中的 $students.isReserved 布尔属性获取totalIsReservedStudents字段。
我尝试通过 $group 获取:
[
{
$addFields: {
gid: { $toString: "$_id" }
}
},
{
$lookup: {
from: 'students',
let: { groupId: "$gid" },
pipeline: [
{
$match: {
$expr: {
$regexMatch: {
input: "$mainGroups",
regex: { $concat: [".*", "$$groupId", ".*"] },
options: "i"
}
}
}
}
],
as: "students"
}
},
{
$addFields: {
studentCount: { $size: "$students" }
}
},
{
$group: {
_id: "$students._id",
totalStudents: {
$sum: 1
},
totalStudentsReserved: {
$sum: {
$cond: {
if: {
$eq: [
"$isReserved",
true
]
},
then: 1,
else: 0
}
}
},
}
},
{
$project: {
_id: 1,
gid: 1,
title: 1,
studentCount: 1,
totalStudents:1,
totalStudentsReserved:1
}
},
]
如何获得预订学生以及团体和学生收藏的总数?
一种选择是在
$lookup
管道内进行分组:
db.groups.aggregate([
{
$addFields: {
gid: {
$toString: "$_id"
}
}
},
{
$lookup: {
from: "students",
let: {
groupId: "$gid"
},
pipeline: [
{
$match: {
$expr: {
$regexMatch: {
input: "$mainGroups",
regex: {
$concat: [
".*",
"$$groupId",
".*"
]
},
options: "i"
}
}
}
},
{
$group: {
_id: null,
count: {
$sum: 1
},
isReserved: {
$sum: {
$cond: [
"$isReserved",
1,
0
]
}
}
}
}
],
as: "students"
}
},
{
$project: {
_id: 1,
gid: 1,
title: 1,
studentCount: {
$ifNull: [
{
$first: "$students.count"
},
0
]
},
isReserved: {
$ifNull: [
{
$first: "$students.isReserved"
},
0
]
}
}
}
])
查看它在 playground 示例中的工作原理