Dan Ramos
Dan Ramos

Reputation: 1102

Mongoose get sum of fields

I'm trying to track the bandwidth usage of a user based upon two mongoose schemas. I have a user and image schema, were a user has many images. My image schema looks like this:

image = {
  creator: 'ObjectId of user',
  size: '12345', //kb
  uploadedTo:[{}]
}

Essentially I want to create a query that will get all images that belong to a user via the image.creator property. I would then multiply the image.size property by image.uploadedTo.length value to get the total bandwidth used.

For example: If a user has 5 images, each image is 5,000kb and is uploaded to 3 services each, the total bandwidth for the user would be 75,000kb (5*5,000*3).

Is this query possible strictly through mongoose, or would I have to just get the user's images and then use regular javascript to get the total bandwidth?

Upvotes: 2

Views: 1654

Answers (1)

Josh Beam
Josh Beam

Reputation: 19772

You'll want to use the aggregation pipeline. The basic projection might look like this:

{
  $project: {
    size: 1,
    number_of_uploads: {
      $size: "$uploadedTo"
    },
    total_bandwidth: {
      $multiply: [ "$size", "$number_of_uploads" ]
    }
}

You'd get a new document that looks like:

{
  size: '1234',
  number_of_uploads: 2,
  total_bandwidth: 2468
}

You'll need to integrate that with Mongoose's aggregate helper.

If you're using MongoDB 3.2, you can also use $lookup (which is basically a join operation) as part of your pipeline to look up the creator._id, and then run a $sum operation on all of the images (you'll probably $group by that creator ID). The benefit of this is that your server doesn't do any work; the lookups and operations happen inside MongoDB itself.

If you're not using v3.2, you can leverage Mongoose's population to look up (on your own server) the creator ID for you, and then use JavaScript on your own server to calculate the sum.

It's a bit difficult for me to come up with what exactly your pipeline will look like since I don't have a sample dataset to play with, but the above tools should be all that you need.

Additional operation resources

(P.S. you're probably looking at this like "WTF?". Sometimes it's easier to just do the calculations yourself and "use regular javascript to get the total bandwidth", as you mentioned. Both solutions will work, it just depends on where you want to put the load - whether on the MongoDB server or on your server - and how many round-trips you want to make.)

Upvotes: 3

Related Questions