0

I have tested the following aggregation on mongodb shell and it works fine, but however it deoes not seem to work with mongoose. I have searched similar topics and issues but their solutions don't solve mine.

The document structure is this

{
  name,
  id,

  contacts:[{
    contactId, //I need an array of this field
    dateAdded
  }, {
    contactId,
    dateAdded
  },
  {}..]
}

The mongooose schema is:

 var AccountSchema = new mongoose.Schema({
    email:     { type: String, unique: true },
    password:  { type: String },
    name: {
      first:   { type: String },
      last:    { type: String },
      full:    { type: String }
    },
    contacts:  [Contact]
  });

And here is the aggregation:

 Account.aggregate({
   $match: { _id: accountId }
 }, {
   $unwind:"$contacts"
 },
 {
   $group: {
     _id: '$_id',
     list: { $push:'$contacts.accountId' }
   }
 }, {
   $project: {
     _id: 0,
     contacts: 1
   }
 }, function(err, doc) {
   // var l=doc.result[0].list;
   callback(doc);  
 });

On the Mongodb shell,the aggregation returns an array of contactID as shown below, but it returns an empty array on Mongoose

{
  "result" : [
    {
      "_id" : null,
      "list" : [
         ObjectId("xxxbnbnb2013-06-23T16:24:03.785Z"),
         ObjectId("mnmnmnmui2013-06-23T16:24:04.688Z")
      ]
    }
  ],
  "ok" : 1
}

1 Answer 1

4

Your query seems to be formatted correctly, I think you've just projected "contacts" when you should have projected "list". I tried to format my data like yours, and the following queries worked for me. In the shell:

db.accounts.aggregate( 
{ $unwind:"$contacts" },
{ $group: {
     _id: '$_id',
     list: { $push:'$contacts.contactId' }
   }
 }, 
{ $project: { _id: 0, list: 1 }} )

or, using the mongoose framework,

Account.aggregate(
     { $unwind:"$contacts" },
     { $group: {
          _id: '$_id',
          list: { $push:'$contacts.contactId' }}},
     { $project: { 
          _id: 0, 
          list: 1 }},
     function (err, res) {
          if (err) //handle error;
          console.log(res);
          }
);

Since you've tried to suppress the "_id" field in the final output of your aggregation query, I'm assuming that you're really just interested in getting a list of all contactIds across all Accounts, and not interested in linking them back to specific Accounts. If you wanted to be left with one long list of contactIds (rather than small documents with one list per original Account), you could run this aggregation query instead:

db.accounts.aggregate( 
{ $unwind:"$contacts" },
{ $group: {
     _id: "allcontacts",
     list: { $push:'$contacts.contactId' }
   }}
 )

or, using the mongoose framework,

Account.aggregate(
     { $unwind:"$contacts" },
     { $group: {
          _id: "allcontacts",
          list: { $push:'$contacts.contactId' }}},
     function (err, res) {
          if (err) ;
          console.log(res);
          }
     );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.