Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDb aggregation $match error : "Arguments must be aggregate pipeline operators"

I can get all stats of the site with aggregation but I want to it for a certain user, like $where.

All stats:

games.aggregate([{
                $group: {
                    _id: '$id',
                    game_total: { $sum: '$game_amount'}, 
                    game_total_profit: { $sum: '$game_profit'}}
                }]).exec(function ( e, d ) {

                    console.log( d )            

            })

When I try to use $match operator, I'm getting error :

games.aggregate([{
                $match: { '$game_user_id' : '12345789' },
                $group: {
                    _id: '$id',
                    game_total: { $sum: '$game_amount'}, 
                    game_total_profit: { $sum: '$game_profit'}}
                }]).exec(function ( e, d ) {

                    console.log( d )            

            })

Arguments must be aggregate pipeline operators

What am I missing?

like image 387
Lazy Avatar asked Oct 16 '14 08:10

Lazy


3 Answers

Pipeline stages are separate BSON documents in the array:

games.aggregate([
                { $match: { 'game_user_id' : '12345789' } },
                { $group: {
                    _id: '$id',
                    game_total: { $sum: '$game_amount'}, 
                    game_total_profit: { $sum: '$game_profit'}}
                }}
]).exec(function ( e, d ) {
    console.log( d )            
});

So the Array or [] bracket notation in JavaScript means it expects a "list" to be provided. This means a list of "documents" which are generally specified in JSON notation with {} braces.

like image 66
Neil Lunn Avatar answered Sep 20 '22 08:09

Neil Lunn


 const stats = await Tour.aggregate([
 
    {
        $match: { ratingsAvarage: { $gte: 4.5 } }
    }, 
    {    
        $group: { 
        _id: null,
        avgRating: { $avg: '$ratingsAvarage' }
                   
         }
    }]

Make sure to separate the pipeline stages with as obj or {} inside the array. So $match and $group have to be inside an object.

like image 45
midnightgamer Avatar answered Sep 18 '22 08:09

midnightgamer


Another possible reason could be due to an empty object {} inside the pipeline. It can happen if you are using any conditional stages in the pipeline.

eg:

const pipeline = []:
.....
.....
let sort = {}
if(params.sort){
 sort = { $sort: { popularity: -1 } }
}

pipeline.push(sort)

This will cause the same error "Arguments must be aggregate pipeline operators"

Instead you can use something like this:

let sort;
if(params.sort){
 sort = { $sort: { popularity: -1 } }
}
    
pipeline.concat(sort? [sort] : [])
like image 42
Sanif SS Avatar answered Sep 18 '22 08:09

Sanif SS