$ Pu sh, если объект еще не существует - PullRequest
5 голосов
/ 02 апреля 2020

У меня есть массив 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"
    }
]

Спасибо!

Ответы [ 2 ]

3 голосов
/ 24 апреля 2020

Вы можете использовать исключение, чтобы удалить идентификатор из документа перед отправкой его в $ 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, чтобы mon goose не генерировал никакого идентификатора для студента.

Что-то вроде

 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"}
  }}
])
1 голос
/ 24 апреля 2020

Вам нужно $unwind, а затем $project, чтобы удалить _id до $group в вашей статистической функции.

Код:

[
  {
    "$match": {
      "teacher.userId": 1
    }
  },
    {
    "$unwind": "$students"
  },
    {
    "$project": {
      "students._id": 0
    }
  },
  {
    "$group": {
      "_id": null,
      "students": {
        "$addToSet": "$students"
      }
    }
  }

]

Пример кода и описание трубопровода

...