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?

Abhilash PS
  • 734
  • 1
  • 11
  • 25

3 Answers3

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

halfer
  • 19,824
  • 17
  • 99
  • 186
Faizul Hassan
  • 120
  • 12
  • 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", []] } } } } } } – Kacper Kwietniewski Jun 28 '20 at 09:58
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.

Gibbs
  • 21,904
  • 13
  • 74
  • 138
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] } }
      }
   },
]);
Faizul Hassan
  • 120
  • 12