Aggregate pipeline throws the error "A pipeline stage specification object must contain exactly one field."

You need to place your pipeline stages in an array, i.e. documents pass through the stages in sequence.

db.collection.aggregate( [ { <stage> }, ... ] )

The $group pipeline step operators should be in their own object/document, not as part of the $match pipeline step. You aggregate pipeline should be

db.audiofiles.aggregate([
    /* match pipeline */
    {
        "$match": {
            "privacy": { "$ne": "same" },
            "date": { "$eq": "2017/04/25" },
            "deleted": 0
        }
    },
    /* group pipeline */
    {
        "$group": { 
            "_id": "$to_email", 
            "count": { "$sum": 1 }
        }
    }
]);

Or create the pipeline steps as object variables that you can push to an array and that array becomes the pipeline to use as the aggregate() method argument:

/* match pipeline */
var match = {
    $match: {
        privacy: { $ne: "same" },
        date: { "$eq": "2017/04/25" },
        deleted: 0
    }
},
/* group pipeline */
group = {
    $group: { 
        "_id": "$to_email", 
        "count": { "$sum": 1 }
    }
};

db.audiofiles.aggregate([match, group]);

If you don't get any response from the above then try to run the aggregate pipeline with just one step:

db.audiofiles.aggregate([match]);

The results from the match step will be piped to the next stage so if you aren't getting any results that means the $match pipeline step hasn't found any matching documents. Change some of the parameters to see if there are any results.


I was also facing same error. My code was :

 db.getCollection('users').aggregate([
      {
          "$lookup":
          {     
              from: 'songs',
              localField: '_id',
              foreignField: 'artistId',              
              as: 'abc'              
          },
          "$project":
          {
              "name":1,
              "status":1,
              "abc":{"artistId":1, "name":1}
          }
      }
])

I resolved by adding { }.

db.getCollection('users').aggregate([
      {
          "$lookup":
          {     
              from: 'songs',
              localField: '_id',
              foreignField: 'artistId',              
              as: 'abc'              
          }
      }, // added braces
      { 
          "$project":
          {
              "name":1,
              "status":1,
              "abc":{"artistId":1, "name":1}
          }
      } // added braces
])

NOTE:: Make sure $lookup and $project should be in different {} braces like :

db.getCollection('users').aggregate([ { $lookup:{} }, { $project: {} } ])

My code was :

 db.getCollection('users').aggregate([ { $lookup:{},  $project: {} } ])