Let's suppose we keep track of attendance for multiple classes. If the student was not attending class on a date, they would not appear in the collection. For example we have class "A" and now we want to find out which student was missing on April 30th 2021 from the previous date:
db = {
"Students": [
{
"date": "2021-04-29",
"student": "Michael",
"class": "A"
},
{
"date": "2021-04-29",
"student": "Sarah",
"class": "A"
},
{
"date": "2021-04-29",
"student": "Thomas",
"class": "A"
},
{
"date": "2021-04-30",
"student": "Michael",
"class": "A"
},
{
"date": "2021-04-30",
"student": "Sarah",
"class": "A"
}
]
}
We would want to retrieve something like this:
[
{
"name": "Thomas",
"class": "A"
}
]
Is that possible?
Possible, yes, but I'm not sure this is the most efficient way.
My idea is to use aggregation:
Note that this all fails if there are no entries for the class for one of the days.
db.Students.aggregate([
{$match: {$or: [{"date": "2021-04-29"}, {"date": "2021-04-30"}]}},
{$group: {
_id: {date: "$date", class: "$class" },
students: { $push: "$student" }
}},
{$sort: {"_id.date": 1}},
{$group: {
_id: "$_id.class",
days: {$push: "$$ROOT"}
}},
{$project: {
_id: 0,
class: "$_id",
name: {$setDifference: [
{"$arrayElemAt": ["$days.students",0]},
{"$arrayElemAt": ["$days.students",1]}
]}
}},
{$unwind: "$name"}
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.