简体   繁体   中英

Filter sub document array in Mongoose and return only matching elements

I've UserSchema that looks like this

const userSchema = mongoose.Schema({
  email: {
    type: String,
    trim: true,
    required: true,
    unique: 1
  },
  password: {
    type: String,
    required: true,
    minlength: 6
  },
  token: {
    type: String
  },
  role: {
    type: Number,
    default: 0 // 0 is student, 1 is admin
  },
  files: [FileSchema],
  internships: [InternshipSchema]
});

As can be seen , files and internships are subdocuments. My goal is to filter either of them based on specific input, eg I would like to filter internships based on country.

However, I'm having a problem of returning only elements that match the search, I can only return all the elements, regardless of search filters being passed in.

I tried to refer querying-subdocument-and-returning-matching-subdocument-only , but could not get it working.

My current code looks like this

app.get("/api/getInternships", (req, res) => {
  User.aggregate(
    {
      $match: {
        "internships.country": req.query.country
      }
    },
    { $unwind: "internships" },
    {
      $match: {
        "internships.country": req.query.country
      }
    }
  );
});

You can try my code:

app.get("/api/getInternships", (req, res) => {
    User.aggregate(
        { $project: { internships: 1 } },
        // after $project
        /* 
        {_id: ObjectId01, internships: [{country: 1}, {country: 2},...]}
        ....
         */
        { $unwind: '$internships' },
        // after $unwind
        /* 
        {_id: ObjectId01, internships: {country: 1}}
        {_id: ObjectId01, internships: {country: 2}}
        ...
         */
        {
            $match: {
                "internships.country": req.query.country
            }
        }
        // final result: [{_id: ObjectId01, internships: {country: 2}}, ...]
    ).exec((err, internships) => {
        if (err) throw err;
        console.log(internships);
        // [{_id: ObjectId01, internships: {country: 2}}, ...]
        // send data to client
        res.status(200).json(internships);
    });
});

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