0

I need help to count the elements of an array when it is in another array.

My command, when I tried to select the second array is,

db.artysci.aggregate([
   {
      $project: {
          _id:0,
         nazwa: 1,
         nazwisko: 1,
         numberOfSongs: { "album": {$size: "$utwor"}}
              
      }
   }
] )

Grid:

db.artysci.insert({
    imie: 'Laurie',
    nazwisko: 'Adkins',
    rok_debiutu: 2006,
    kraj_pochodzenia: ['Wielka Brytania'],
    gatunek: 'neo soul',
    album: [{
            tytul:"19",
            rok_edycji:2007,
            gatunek: 'pop',
            typ_nosnika: 'CD',
            utwor: [{
                    numer: 1,
                    tytul_utworu: 'Daydreamer',
                    dlugosc_trwania: 3.41
                    },
                    {
                    numer: 2,
                    tytul_utworu: 'Best for Last',
                    dlugosc_trwania: 4.19
                    },
                    {
                    numer: 3,
                    tytul_utworu: 'Chasing Pavements',
                    dlugosc_trwania: 3.31
                    }
                    ]
            }]
          })

Output when counting by $size:"$album",

{ 
    "nazwisko" : "Adkins", 
    "numberOfSongs" : {
        "album" : NumberInt(3)
    }
}

How can I count elements of an array in an array by $size?

3 Answers 3

1

You can achieve this using Map and then summing it up. It works..

db.artysci.aggregate({
    "$project": {
        _id: 0,
        nazwa: 1,
        nazwisko: 1,
        "numberOfAlbums": { "$size": { $ifNull: ["$album", []] } },
        "numberOfSongs": {
            "$sum": {
                "$map": {
                    "input": "$album",
                    "in": { "$size": { $ifNull: ["$$this.utwor", []] } }
                }
            }
        }
    }
})

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Faizul Hassan, can you help me with one more thing, please? I need to do avg/60(in secounds) of all songs. Is it good way to do it? "avgOfSongTime": { "$avg": { "$map": { "input": "$album", "$map":{ "input": "$utwor", "in": { "$avg": { $ifNull: ["$$this.dlugosc_trwania", []] } } } } } }
0

@Kacper,

Here is the soultion for your second question.

Yes, you can achieve it in either way, using the above method or using unwind and do the average..

Lets see an example using unwind:

Without divide/second:

 db.notifications.aggregate([
       { $unwind: "$album" },
       { $unwind: "$album.utwor" },
       {
          $group: {
             _id: "$_id",
             avgDuration: { $avg: "$album.utwor.dlugosc_trwania" }
          }
       },
    ]);

With divide/second:

db.notifications.aggregate([
   { $unwind: "$album" },
   { $unwind: "$album.utwor" },
   {
      $group: {
         _id: "$_id",
         avgDuration: { $avg: { $divide: ["$album.utwor.dlugosc_trwania", 60] } }
      }
   },
]);

Comments

0

You can use $unwind and $group to get the counts.

db.collection.aggregate([
  {
    $unwind: "$album"
  },
  {
    $unwind: "$album.utwor"
  },
  {
    $group: {
      _id: 0,
      total: {
        $sum: 1
      }
    }
  }
])

Play

If you need more information, add it to your question.

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.