首页 > 解决方案 > $Push 如果对象不存在

问题描述

students我的文档中有一系列,VirtualClass我的目标是创建一个没有重复学生的名册。

我想将VirtualClass与老师匹配,然后$push将学生匹配到一个数组中。

虚拟类模式

const VirtualClassSchema = new Schema({
  name: { type: String, required: true },
  descriptionHeading: { type: String, required: true },
  room: { type: String },
  teacher: {
    userId: { type: Schema.Types.ObjectId, ref: "User" },
    name: { type: String },
    profile_picture: { type: String }
  },
  students: [
    {
      userId: { type: Schema.Types.ObjectId, ref: "User" },
      name: { type: String },
      profile_picture: { type: String }
    }
  ],
...

我目前的查询如下

      VirtualClass.aggregate([
        { $match: { "teacher.userId": user._id } },
        {
          $group: {
            _id: null,
            students: { $addToSet: "$students" }
          }
        }
      ])

返回:

[
    {
        "_id": null,
        "students": [
            [
                {
                    "_id": "5e84d1a1ab3ebf54283b8cb2",
                    "userId": "5dd27452592f600900235945",
                    "name": "student  zero",
                    "profile_picture": "https://productionstemulistorage.blob.core.windows.net/stemuli/profile-picture-6e609f3b-44cb-44c0-888a-1b6767e3072d"
                }
            ],
            [
                {
                    "_id": "5e84d1a1ab3ebf54283b8cb4",
                    "userId": "5dd27452592f600900235945",
                    "name": "student  zero",
                    "profile_picture": "https://productionstemulistorage.blob.core.windows.net/stemuli/profile-picture-6e609f3b-44cb-44c0-888a-1b6767e3072d"
                }
            ]
        ]
    }
]

预期成绩:

_id: null,
"students":
[
     {
       "_id": "5e84d1a1ab3ebf54283b8cb4",
        "userId": "5dd27452592f600900235945",
        "name": "student  zero",
        "profile_picture": "https://productionstemulistorage.blob.core.windows.net/stemuli/profile-picture-6e609f3b-44cb-44c0-888a-1b6767e3072d"
    }
]

谢谢!

标签: mongodbaggregation-framework

解决方案


您可以使用排除在将文档发送到 $addToSet 之前将其从文档中删除。你的学生也是数组,所以你需要$unwind.

就像是

VirtualClass.aggregate([
  {$match:{"teacher.userId": user._id}},
  {$project:{"students._id": 0}},
  {$unwind: "$students"},
  {$group:{
      _id: null,
      students: {$addToSet:"$students"}
  }}
])

这里的例子 - https://mongoplayground.net/p/zULrmihM03z

输出

[
  {
    "_id": null,
    "students": [
      {
        "name": "student  zero",
        "profile_picture": "https://productionstemulistorage.blob.core.windows.net/stemuli/profile-picture-6e609f3b-44cb-44c0-888a-1b6767e3072d",
        "userId": "5dd27452592f600900235945"
      }
    ]
  }
]

另一种选择是将_id设置为false,这样猫鼬就不会为学生生成任何ID。

就像是

 students: [
    {
      userId: { type: Schema.Types.ObjectId, ref: "User" },
      name: { type: String },
      profile_picture: { type: String },
      _id:false
    }
  ],

然后,您可以使用不排除的聚合查询。

VirtualClass.aggregate([
  {$match:{"teacher.userId": user._id}},
  {$unwind: "$students"},
  {$group:{
      _id: null,
      students: {$addToSet:"$students"}
  }}
])

推荐阅读