简体   繁体   中英

Mongoose: How to extract arrays in subdocuments to a single array in the parent document

An Express server using Mongoose returns the following JSON from the database in one of its routes:

{
  "gradeLevel": 12,
  "classes": [
    {
      "className": "A",
      "students": [
        "student1", "student2","student3"
      ]
    },
    {
      "className": "B",
      "students": [
        "student4", "student5","student6"
      ]
    },
    {
      "className": "C",
      "students": [
        "student7", "student8","student9"
      ]
    }
  ]
}

In the client, I'd like to be able to for example efficiently check if a student is in any of the class subdocuments in the parent document. The following are the solutions I've conceived, but am not sure which is best practice:

  1. When a student is pushed to class subdocument, push the student to the parent's students field as well.
  2. Add a new field in the model's toJSON transformation to compile all the students.
  3. Use vanilla Javascript in the client to extract all students

I was at this problem too. But to tackle this you need a separate collection called allStudents for example where the schema of it is as follows { nameOfStudent: 'String' className: 'String' }

then aggregate it accordingly with subdoucment. So that wherever you push a new student into allStudents with the className mentioned it will be pushed to the students subdocument of the respective className.

Querying with dot notation, like

.find({"classes.students":"student8"})

will check the students field of each object in the classes array, returning the documents containing the specific student in any class.

Thank you for the answers given. Just sharing another solution using vanilla Javascript that might be of use to those in similar situations:

  checkStudent = (batch, student) => {
    let result = null
    const inClass = (cls) => {
      if (cls.students.includes(student)) {
        result = cls
        return true
      }
      return false
    }
    batch.classes.some(inClass)
    return result
  }

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