Dipak
Dipak

Reputation: 493

How to filter $match equals to object value using aggregate query in mongoose

I have the following Record in Mongo Database

{
    "_id" : ObjectId("54a0d4c5bffabd6a179834eb"),
    "is_afternoon_scheduled" : true,
    "employee_id" : ObjectId("546f0a06c7555ae310ae925a"),
    "currDate" : ISODate("2014-12-28T18:30:00Z"),
    "modified_date" : ISODate("2014-12-29T04:12:53.677Z"),
    "modified_by" : ObjectId("541a9c223416b36f67cfbfe8"),
    "__v" : 0,
    "manager_schedule" : {
        "afternoon_schedule_details" : {
            "event" : ObjectId("54507897cecff53914c82b6d"),
            "is_afternoon_scheduled" : true
        },
        "modified_by" : ObjectId("541a9c223416b36f67cfbfe8"),
        "modified_date" : ISODate("2014-12-29T04:13:00.432Z")
    }
}

I would like to Filter aggregate with $match equals to employee_id. i am using the below query in mongoose but i didn't get any result with query. something is wrong with method or query. but when i run this query directly in mongodb i get the correct result. Need help in this.

Availability.aggregate() 
            .match( { employee_id : "546f0a06c7555ae310ae925a" } )
            .group({_id : "$employee_id",count: { $sum: 1 }})
            .exec(function (err, response) {
              if (err) console.log(err);
              res.json({"message": "success", "data": response, "status_code": "200"});
            }
        );

Upvotes: 2

Views: 4112

Answers (2)

Neil Lunn
Neil Lunn

Reputation: 151220

It would be kind of nice if the Mongoose helper .match() method here did something like what the other query and update helpers do. But there is a good reason why it doesn't I guess.

You can just throw a string like this at a regular .find() query in Mongoose because the schema defined for the model you use is applied to "cast" the types of any fields used in the query object. So it would just 'coerce' the string into an ObjectId value.

Maybe some smarts could be built in here to realize that this was the "first" pipeline stage, but the main reason this does not work in the same way is because the aggregation framework is meant to "alter" documents away from the defined schema structure they originally come with.

So you need to import the ObjectId() function and use that to cast the value properly:

var ObjectId = require('mongodb').ObjectID();

Availability.aggregate() 
            .match( { employee_id : ObjectId("546f0a06c7555ae310ae925a") } )
            .group({_id : "$employee_id",count: { $sum: 1 }})
            .exec(function (err, response) {
              if (err) console.log(err);
              res.json({"message": "success", "data": response, "status_code": "200"});
            }
        );

You need to do this manually because it cannot do it for you.

Upvotes: 1

BatScream
BatScream

Reputation: 19700

Use the function mongoose.Types.ObjectId() to obtain the ObjectId() for the string and then use it to query in the $match stage.

var val = mongoose.Types.ObjectId("546f0a06c7555ae310ae925a");
Availability.aggregate() 
            .match( { employee_id : val} )
            .group({_id : "$employee_id",count: { $sum: 1 }})
            .exec(function (err, response) {
              if (err) console.log(err);
              res.json({"message": "success", "data": response, 
                        "status_code": "200"});
            }
);

Upvotes: 1

Related Questions