Benjamin
Benjamin

Reputation: 727

how to aggregate after populate with mongoose

I'm working with mongoose, and I have a problem in doing aggregate after populate. Belows are an example.

There are two mongoose model schema, monster and collection.

const monster = new Schema({
    name: { type: String },
    power: { type: Number },
    armor: { type: Number },
});

const collection = new Schema({
    _monster: { type: Schema.Types.ObjectId, ref: 'Monster' },
    addedPower: { type: Number },
    addedArmor: { type: Number },
});

As you see, field '_monster' is foreign key of schema 'collection' to schema 'monster'.

I want to populate 'monster' and 'collection' using this path like below.

Collection.find().populate('_monster')

And I want to aggregate this result like below.

AboveResult.aggregate([
    {
        '$project': {
            'new_field': { 
                '$add': [ 
                     '$addedPower', '$addedArmor', '$_monster.power', '$_monster.armor' 
                ]
            }
        }
    }
]);

Above doesn't work, but I think it would explain about what I want. Answer will be thanksful.

Upvotes: 5

Views: 5136

Answers (1)

chridam
chridam

Reputation: 103365

You can use $lookup as an alternative for the populate and this is done on the server:

Collection.aggregate([
    {
        "$lookup": {
            "from": "monsters",
            "localField": "_monster",
            "foreignField": "_id",
            "as": "monster"
        }
    },
    { "$unwind": "$monster" },
    {
        "$project": {
            "name": "$monster.name",
            "power": "$monster.power",
            "armor": "$monster.armor",
            "addedPower": 1,
            "addedArmor": 1,
            'new_field': { 
                '$add': [ 
                    '$addedPower', 
                    '$addedArmor', 
                    '$monster.power', 
                    '$monster.armor' 
                ]
            }
        }
    }
]).exec(callback);

Upvotes: 8

Related Questions