title: MongoDB - get documents with the size of a nested array after filtering
body: <p><strong>Problem:</strong></p>
  
  <p>I'm trying to get a list of documents and for each one of them to calculate the number of occurrences of a given value in a nested array of the same document.</p>
  
  <p>I have a working example using the aggregation framework, but I wonder if there is a better way to accomplish the same thing, so I can benchmark the different approaches. </p>
  
  <p><strong>Simplified Data Model:</strong></p>
  
  <p><em>Single document in collection "Raffles":</em></p>
  
  <pre><code>{
    "_id" : objectId,
    "name" : string,
    "ends_at" : ISODate/Timestamp,
     ...
    "subscribers" : string[] //List of user ids
  }
  </code></pre>
  
  <ul>
  <li>The collections consists of documents representing a raffle/sweepstake with a name and start/ending dates. </li>
  <li>Users can subscribe to a raffle. </li>
  <li>Users can subscribe multiple times for the same raffle.</li>
  </ul>
  
  <p>95% of the read queries will require both the raffle data like name, description and dates + information about the subscribed users. That's why I decided to have everything in a single raffle document instead of: referencing the subscribed raffles in the user document or having a separate collection with raffles and subscription counts.</p>
  
  <p><em>Alternative maybe?:</em></p>
  
  <p>The <code>subscribers</code> array is a list of strings representing the user's ID. This way adding a subscriber is as simple as pushing a new value. The other option is to have an array of objects like this and incrementing the count:</p>
  
  <pre><code>{
    "subscribers: [
       {
         "id": objectId  //User id
         "count": integer //Number of subscriptions
       },
       ...
    ]
  }
  </code></pre>
  
  <p><strong>Expected result:</strong></p>
  
  <p>The expected result is to have the full raffle document + an additional value of how many subscriptions a given user has.</p>
  
  <pre><code>{
      "_id" : objectId,
      "name" : string,
      "ends_at" : ISODate/Timestamp,
       ...
      "subscriptions" : 3 //Number of entries for a given user
  }
  </code></pre>
  
  <p><strong>Current solution</strong></p>
  
  <p>I'm getting the size after filtering the nested array with a given user id &lt; USER_ID ></p>
  
  <pre><code>db.raffles.aggregate([
      ...
      {
          $project: {
              "name" : 1,
              "ends_at" :1,
               ...
              "subscriptions" : {
                   $size : {
                      $filter : {
                          input: "$subscribers",
                          as: "user",
                          cond: {
                              $eq: ["$$user", &lt;USER_ID&gt;]
                          },
                      }
                   }
              }
          }
      }
      ...
  ])
  </code></pre>
  
  <p><strong>Questions:</strong></p>
  
  <ul>
  <li><p>Are there other/better ways to accomplish the result from the current solution? Maybe grouping and summing up or map/reduce?</p></li>
  <li><p>Is it worth keeping not only the user ids, but rather objects with user id and subscription count?</p></li>
  <li><p>The current solution will throw an error if the <code>subscriptions</code> array is not set. Is there a way to handle this?</p></li>
  </ul>
  
  <p><em>Thank you very much for the time spent reading this long post!</em></p>