Project with Match in aggregate not working in mongodb

[问题]


2down votefavorite

I am trying to fetch data based on some match condition. First I've tried this: Here ending_date is full date format

    Offer.aggregate([

    {

        $match: {

            carer_id : req.params.carer_id,

            status : 3

        }

    },

    {

        $group : {

            _id : { year: { $year : "$ending_date" }, month: { $month : "$ending_date" }},

            count : { $sum : 1 }

        }

    }],

    function (err, res)

    { if (err) ; // TODO handle error

         console.log(res);

    });

which gives me following output:

[ { _id: { year: 2015, month: 11 }, count: 2 } ]

Now I want to check year also, so I am trying this:

    Offer.aggregate([

    {

        $project: {

            myyear: {$year: "$ending_date"}

        }

    },

    {

        $match: {

            carer_id : req.params.carer_id,

            status : 3,

            $myyear : "2015"

        }

    },

    {

        $group : {

            _id : { year: { $year : "$ending_date" }, month: { $month : "$ending_date" }},

            count : { $sum : 1 }

        }

    }],

    function (err, res)

    { if (err) ; // TODO handle error

         console.log(res);

    });

which gives me following output:

 []

as you can see, _id has 2015 as a year, so when I match year it should be come in array. But I am getting null array. Why this?

Is there any other way to match only year form whole datetime?

Here is the sample data

{

    "_id": {

        "$oid": "56348e7938b1ab3c382d3363"

    },

    "carer_id": "55e6f647f081105c299bb45d",

    "user_id": "55f000a2878075c416ff9879",

    "starting_date": {

        "$date": "2015-10-15T05:41:00.000Z"

    },

    "ending_date": {

        "$date": "2015-11-19T10:03:00.000Z"

    },

    "amount": "850",

    "total_days": "25",

    "status": 3,

    "is_confirm": false,

    "__v": 0

}

{

    "_id": {

        "$oid": "563b5747d6e0a50300a1059a"

    },

    "carer_id": "55e6f647f081105c299bb45d",

    "user_id": "55f000a2878075c416ff9879",

    "starting_date": {

        "$date": "2015-11-06T04:40:00.000Z"

    },

    "ending_date": {

        "$date": "2015-11-16T04:40:00.000Z"

    },

    "amount": "25",

    "total_days": "10",

    "status": 3,

    "is_confirm": false,

    "__v": 0

}

[回答]

You forgot to project the fields that you're using in $match and $group later on. For a quick fix, use this query instead:

Offer.aggregate([
{
    $project: {
        myyear: { $year: "$ending_date" },
        carer_id: 1,
        status: 1,
        ending_date: 1
    }
},
{ 
    $match: { 
        carer_id: req.params.carer_id,
        myyear: 2015,
        status: 3
    }
},
{
    $group: {
        _id: {
            year: { $year: "$ending_date" },
            month: { $month: "$ending_date" }
        }, 
        count: { $sum: 1 }
    }
}], 
function (err, res)
{
    if (err) {} // TODO handle error 
    console.log(res); 
});

That said, Blakes Seven explained how to make a better query in her answer. I think you should try and use her approach instead.

也就是说,project的字段中必须包含match中用到的字段.

来自: https://stackoverflow.com/questions/33752817/project-with-match-in-aggregate-not-working-in-mongodb

原文地址:https://www.cnblogs.com/time-is-life/p/9328680.html