1

I've the following structure of documents in MongoDB. The array records contain different persons that have the roles teacher or student.

[
    {_id: 1, persons: [{role:"teacher", name: "Mark", school: "", county: "Oneida"}, {role:"student", name: "John", school: "LM High School", county:""}]},
    {_id: 2, persons: [{role:"teacher", name: "Robert", school: "", county: "Onondaga"}, {role:"student", name: "David", school: "Beaker High School", county:""}}]}
]

I need to get the output in the following format. From the first matching teacher person I need to select county, and from the first matching student person I need to select the school. I need to project both school and county from the nested array element level to the root document level.

[
    {_id: 1, county: "Oneida", school: "LM High School"},
    {_id: 2, county: "Onondaga", school: "Beaker High School"}
]

What can be the appropriate aggregation step? I tried several steps like arrayElemAt, projection, etc. but couldn't get the correct one.

0

1 Answer 1

1
  • $filter to iterate loop of persons array and filter teachers and students separately
  • to get the first element from the array, use $first from MongoDB 4.4, for below you can use $arrayElemAt
db.collection.aggregate([
  {
    $project: {
      teacher: {
        $filter: {
          input: "$persons",
          cond: { $eq: ["$$this.role", "teacher"] }
        }
      },
      student: {
        $filter: {
          input: "$persons",
          cond: { $eq: ["$$this.role", "student"] }
        }
      }
    }
  },
  {
    $project: {
      county: { $first: "$teacher.county" },
      school: { $first: "$student.school" }
    }
  }
])

Playground

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! For the second step $first didn't work for me. I had to use something like county: { $arrayElemAt: ["$teacher.county",0] }
okay, $first will work from mongodb v4.4.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.