16

I'm trying to sum some values in an array of documents, with no luck.

This is the Document

db.Cuentas.find().pretty()

{
    "Agno": "2013",
    "Egresos": [
        {
            "Fecha": "28-01-2013",
            "Monto": 150000,
            "Detalle": "Pago Nokia Lumia a @josellop"
        },
        {
            "Fecha": "29-01-2013",
            "Monto": 4000,
            "Detalle": "Cine, Pelicula fome"
        }
    ],
    "Ingresos": [],
    "Mes": "Enero",
    "Monto": 450000,
    "Usuario": "MarioCares"
    "_id": ObjectId(....)
}

So, i need the sum of all the "Monto" in "Egresos" for the "Usuario": "MarioCares". In this example 154000

Using aggregation i use this:

db.Cuentas.aggregate(
    [
        { $match: {"Usuario": "MarioCares"} },
        { $group: 
            {
                _id: null,
                "suma": { $sum: "$Egresos.Monto" }
            }
        }
    ]
)

But i always get

{ "result" : [{ "_id" : null, "suma" : 0 }], "ok" : 1 }

What am i doing wrong ?

P.D. already see this and this

3
  • 1
    I believe you want to unwind the Egresos array first and then group on null and sum Commented Jan 28, 2013 at 20:27
  • @Sammaye added {"$unwind": $Egresos } and then i got ReferenceError: Egresos is not defined Commented Jan 28, 2013 at 20:35
  • You can simplify to use below code in latest versions for summing array values in a single document.db.Cuentas.aggregate([ {$match: {"Usuario": "MarioCares"} }, {$project: { "suma": {$sum: "$Egresos.Monto" }}} ]) Commented Dec 13, 2017 at 22:00

3 Answers 3

29

As Sammaye indicated, you need to $unwind the Egresos array to duplicate the matched doc per array element so you can $sum over each element:

db.Cuentas.aggregate([
    {$match: {"Usuario": "MarioCares"} }, 
    {$unwind: '$Egresos'}, 
    {$group: {
        _id: null, 
        "suma": {$sum: "$Egresos.Monto" }
    }}
])
Sign up to request clarification or add additional context in comments.

Comments

11

You can do also by this way. don't need to group just project your fields.

db.Cuentas.aggregate([
    { $match: { "Usuario": "MarioCares" } },
    {
        $project: {
            'MontoSum': { $sum: "$Egresos.Monto" }
        }
    }
])

4 Comments

Can you give example or snippet?
I AM SORRY @Aabid . It did not work because i was having a little different scenario in which lets say the Egresos was also a variable in the same project stage... But it does work in the scenario of this question..
@DagaArihant So this worked for the question you asked?
I am sorry, My case was different and i did not ask question.
0

Since mongoDB version 3.4 you can use $reduce to sum array items:

db.collection.aggregate([
  {
    $match: {Usuario: "MarioCares"}
  },
  {
    $project: {
      suma: {
        $reduce: {
          input: "$Egresos",
          initialValue: 0,
          in: {$add: ["$$value", "$$this.Monto"]}
        }
      }
    }
  }
])

Playground example

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.