styopdev
styopdev

Reputation: 2664

Select fields' values as array mongoose / mongodb aggregation

I have a mongo query

db.memberships.aggregate([{
        '$match': {
            unit: new ObjectId('566fbaa1e63225b10bacac44')
        }
    },

    {
        '$lookup': {
            from: 'seasons',
            localField: 'season',
            foreignField: '_id',
            as: 'season'
        }
    },

    {
        '$unwind': '$season'
    },
    {
        '$project': {
            season: {
                'name': '$season.name',
                'id': '$season._id'
            }
        }
    },
    {
        '$group': {
            _id: '$_id',
            'season': {
                '$addToSet': '$season'
            }
        }
    },

]);

Which results in

[
    {
        "_id": ObjectId("56a0e5a860d8a6e41eda2ea3"),
        "season": [{
            "name": "Summer",
            "id": ObjectId("56a0d6c692c26b8c019a2758")
        }]
    },
    {
        "_id": ObjectId("56a0e56d60d8a6e41eda2e9e"),
        "season": [{
            "name": "Summer",
            "id": ObjectId("56a0d6c692c26b8c019a2758")
        }]
    },
    {
        "_id": ObjectId("56a0e53860d8a6e41eda2e9a"),
        "season": [{
            "name": "Summer",
            "id": ObjectId("56a0d6c692c26b8c019a2758")
        }]
    },

    {
        "_id": ObjectId("56a0e4d660d8a6e41eda2e94"),
        "season": [{
            "name": "Winter",
            "id": ObjectId("5680dc01ba1e41f5066526fa")
        }]
    }
]

I need to get the result in this format

{
    _id: [
        // ids here
    ],
    seasons: [{
            id: '56a0d6c692c26b8c019a2758',
            'name': 'Summer'
        },
        {
            id: '5680dc01ba1e41f5066526fa',
            'name': 'Winter'
        }
    ]
}

Query must return a single document with 2 properties id and season. Seasons must be an array of unique seasons. Every season should contain an id and a name. Thanks for help!

Upvotes: 1

Views: 1908

Answers (1)

chridam
chridam

Reputation: 103305

Restructure you pipeline with your $group step to have an _id value of null to calculate accumulated values for all the input documents as a whole, thus creating the id field as an array of all the unique ids:

var pipeline = [ 
    { 
        '$match': { 
            unit: new ObjectId('566fbaa1e63225b10bacac44')
        } 
    },

    { 
        '$lookup': { 
            from: 'seasons', localField: 'season', foreignField: '_id', as: 'season' 
        } 
    },
    {
        '$unwind' : '$season'
    },
    {
        '$project': {
            season:  {'name': '$season.name', 'id' : '$season._id'}
        }
    },
        { 
        '$group': {
            "_id": null,  
            "id": { "$addToSet": "$_id" },
            'season': { 
                '$addToSet': '$season' 
            }
        } 
    }       
];
db.memberships.aggregate(pipeline);

Upvotes: 2

Related Questions