0

I've a schema which has an array inside and I want to select an item but exclude some of the array elements which have a specific value.

Sample data:

{
  _id: 1,
  name: something,
  department: management,
  employees: [
    0: { 
      _id: 1,
      name: joe,
      suspended: false
    },
    1: {
      _id: 2,
      name: clare,
      suspended: false
    },
    2: {
      _id: 3,
      name: michelle,
      suspended: true
    }

  ]
}

I need to exclude clare and joe and all the others has suspended:false from the result. (I need to get the department and it's suspended employees inside)

Here is the code I tried but it didn't work... This code is excluding "suspended" field only. Not the array elements.

Department.findOne(
    { name:req.params.department},
    { 'employees.suspended': false }
    , function(err, result){
        if(err) {
            console.log("ERROR");
            console.log(err);
        } else {
            console.log("RESULT");
            console.log(result);
        }
    })

2 Answers 2

1

You can do it with MongoDB Aggregation framework

Department.aggregate([
  {
    $match: {
      name: req.params.department
    }
  },
  {
    $addFields: {
      employees: {
        $filter: {
          input: "$employees",
          cond: {
            $ne: [
              "$$this.suspended",
              false
            ]
          }
        }
      }
    }
  }
]).exec(err, result){
    if(err) {
        console.log("ERROR");
        console.log(err);
    } else {
        console.log("RESULT");
        console.log(result);
    }
})

MongoPlayground

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

7 Comments

Working correctly on MongoPlayground but it returns an empty array on mongoose.
@UtkuDemir make sure req.params.department has valid string value
It's my bad. I was trying to match with _id but I didn't know I need to convert string to ObjectId first. So this is working code for $match now: $match: { "_id": mongoose.Types.ObjectId(req.params.id) }
@UtkuDemir excellent. You add more pipeline to aggregation to filter and transform your data
thanks a lot. I've got one last question... Let's say I want to exclude employees names from the result to reduce response size... What should I do?
|
0

Try this one:

db.collection.aggregate([
   { $match: { name: req.params.department } },
   {
      $set: {
         employees: {
            $filter: {
               input: "$employees",
               cond: "$$this.suspended"
            }
         }
      }
   }
])

Mongo playground

1 Comment

It's filtering employees correctly but there're lots of departments and I need to select just one by name. I tried to use "$match" but returned an empty array.

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.