Wrong
Wrong

Reputation: 1263

Spring data mongo - Get sum of array of object

I have the following document:

{
   pmv: {
        budgets: [
           {
              amount: 10
           },
           {   
              amount: 20
           }
         ]
     }
}

and I need to sum the amount field from every object in budgets. But it's also possible that the budget object doesn't exist so I need to check that.

How could I do this? I've seen many questions but with projections, I just need a integer number which in this case would be 30.

How can I do it?

Thanks.

EDIT 1 FOR PUNIT

This is the code I tried but its giving me and empty aray

AggregationOperation filter = match(Criteria.where("pmv.budgets").exists(true).not().size(0));
            AggregationOperation unwind = unwind("pmv.budgets");
            AggregationOperation sum = group().sum("budgets").as("amount");

            Aggregation aggregation = newAggregation(filter, unwind, sum);

            mongoTemplate.aggregate(aggregation,"Iniciativas",String.class);

            AggregationResults<String> aggregationa = mongoTemplate.aggregate(aggregation,"Iniciativas",String.class);

            List<String> results = aggregationa.getMappedResults();

Upvotes: 0

Views: 1765

Answers (1)

Punit Tiwan
Punit Tiwan

Reputation: 106

You can do this with aggregation pipeline

db.COLLECTION_NAME.aggregate([
  {"pmv.budgets":{$exists:true,$not:{$size:0}}},
  {$unwind:"$pmv.budgets"},
  {amount:{$sum:"$pmv.budgets"}}
]);

This pipeline contains three queries:

  1. get document having non-null and non-empty budgets
  2. $unwind basically open the array and create one document for each array element. e.g. if one document of budgets has 3 elements then it will create 3 document and fill budgets property from each of the array element. You can read more about it here
  3. sum all the budgets property using $sum operator

You can read more about aggregation pipeline here

EDIT: as per comments, adding code for java as well.

AggregationOperation filter = match(Criteria.where("pmv.budgets").exists(true).not().size(0));
AggregationOperation unwind = unwind("pmv.budgets");
AggregationOperation sum = group().sum("pmv.budgets").as("amount");

Aggregation aggregation = newAggregation(filter, unwind, sum);

mongoTemplate.aggregate(aggregation,COLLECTION_NAME,Output.class);

You can do this in more inline way as well but I wrote it like this so that it will be easy to understand.

I hope this answer your question.

Upvotes: 2

Related Questions