简体   繁体   中英

MongoDB Retrieving data that is missing in collection

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:

  • $match to select the days in question
  • $group with $push to make an array of students for each day
  • $sort to make sure the days are in the right order
  • $group to get both arrays into a single document
  • $project with $setDifference to subtract the second day's array from the first
  • $unwind to list each student separately

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"}
])

Playground

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM