What happened to this mongoskin aggregation team?

I have a mongodb / mongoskin aggregation request like this:

db.collection(customerTable + '_earnedinfluencers').aggregate([
    {
        $group: {
            _id: '$user',
            name: '', // to be filled separately
            username: '', // to be filled separately 
            picture: '', // to be filled separately
            city: '', // to be filled separately
            kids: { $sum: '$kids' },
            revenue: { $sum: '$dayIncome' },
            kidsRevRatio: { $divide: [ { $sum: '$kids' }, { $sum: '$dayIncome' } ] }
        }, 

        $match: {
            richness: { $gte: variable1 },
            kids: { $lt: variable2 },
            hobbies: { $in: ['hobby1', 'hobby2', 'hobby3', 'hobby4'] },
            event: { $in: schoolfestival },
            event: { $ne: 0 }
        },

        $project: {
            _id: 0,
            user: '$_id',
            name: 1,
            username: 1,
            picture: 1,
            city: 1,
            kids: 1,
            revenue: 1,
            kidsRevRatio: 1
        }
    }
], function(err, result) {
    // do something with err and result
});

      

The above code gives the following error:

Error: {"name":"MongoError","errmsg":"exception: A pipeline stage specification object must contain exactly one field.","code":16435,"ok":0}

      

I am new to mongo and db in general and cannot tell what I did wrong.

+3


source to share


1 answer


Your pipeline arguments are not balanced, each stage is a separate document, so you need to wrap them. But there are a number of other problems.

db.collection(customerTable + '_earnedinfluencers').aggregate([

    { $match: {
            richness: { $gte: variable1 },
            kids: { $lt: variable2 },
            hobbies: { $in: ['hobby1', 'hobby2', 'hobby3', 'hobby4'] },
            event: { $in: schoolfestival },
    }},

    { $group: {
            _id: '$user',
            name: { '$first': '$name' },
            username: { '$first': '$username' },
            picture: { '$first': '$picture' },
            city: { '$first': '$city' }
            kids: { '$sum': '$kids' },
            revenue: { '$sum': '$dayIncome' },
            kidsSum: { '$sum': '$kids' },
    }}, 


    { $project: {
            _id: 0,
            user: '$_id',
            name: 1,
            username: 1,
            picture: 1,
            city: 1,
            revenue: 1,
            kidsSum: 1,
            kidsRevRatio: { $divide: [ '$kidsSum', '$revenue' ] }
    }}
], function(err, result) {
    // do something with err and result
});

      

You had your entire pipeline as one , which actually requires an array of documents as shown.

But first you want to filter the results. If you really want to do additional matching after the group, then after that you add additional matching to the pipeline. $match



The operation requires that all fields outside the grouping key must have a "grouping operator", you cannot simply return the fields yourself if they are not part of the grouping you are grouping. Usually you need an operator, for example , or else omit them entirely. $group

_id

_id

$first

Top-level grouping operators, so type operations are not grouping operations. To do this, when you are working on one or more results , you move that to a later one using calculated fields. $divide

$sum

$project

Also, operations such as project and group "remove" fields from the pipeline and only keep the ones you specifically include. Therefore, you cannot specify a field that is not there. This is one of the reasons why you should first $match

, as well as where you can use the index, and only ever at the beginning of the pipeline can it be done.

But for each stage, only those fields will be indicated that are indicated. As an additional optimization, the "optimizer" does not include any fields present in your document that are not specifically mentioned from the start. Thus, only those referenced in the first match and group stages will be included for the rest of the track stages and then possibly filtered out again.

+11


source







All Articles