简体   繁体   English

MongoDB 检索集合中缺少的数据

[英]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.如果学生在某个日期没有参加 class,他们将不会出现在集合中。 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:例如,我们有 class “A”,现在我们想找出前一个日期在 2021 年 4 月 30 日失踪的学生:

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 $match 到 select 有问题的日子
  • $group with $push to make an array of students for each day $group 和 $push 为每天创建一个学生数组
  • $sort to make sure the days are in the right order $sort 以确保日期的顺序正确
  • $group to get both arrays into a single document $group 将 arrays 合并到一个文档中
  • $project with $setDifference to subtract the second day's array from the first $project 与 $setDifference 从第一天减去第二天的数组
  • $unwind to list each student separately $unwind 分别列出每个学生

Note that this all fails if there are no entries for the class for one of the days.请注意,如果某一天没有 class 的条目,这一切都会失败。

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操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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