Q:

How to $add together a subset of elements of an array in mongodb aggregation?

Here is the problem I want to resolve:

each document contains an array of 30 integers
the documents are grouped under a certain condition (not relevant here)
while grouping them, I want to:

add together the 29 last elements of the array (skipping the first one) of each document
sum the previous result among the same group, and return it

Data structure is very difficult to change and I cannot afford a migration + I still need the 30 values for another purpose. Here is what I tried, unsuccessfully:
db.collection.aggregate([
    {$match: {... some matching query ...}},
    {$project: {total_29_last_values: {$add: ["$my_array.1", "$my_array.2", ..., "$my_array.29"]}}},
    {$group: {
        ... some grouping here ...
        my_result: {$sum: "$total_29_last_values"}
    }}
])

Theoretically (IMHO) this should work, given the definition of $add in mongodb documentation, but for some reason it fails:
exception: $add only supports numeric or date types, not Array

Maybe there is not support for adding together elements of an array, but this seems strange...
Thanks for your help !

A:

From the docs,

The $add expression has the following syntax:
{ $add: [ <expression1>, <expression2>, ... ] }
The arguments can be any valid expression as long as they resolve to
  either all numbers or to numbers and a date.

It clearly states that the $add operator accepts only numbers or dates.
$my_array.1 resolves to an empty array. for example, []. (You can always look for a match in  particular index, such as, {$match:{"a.0":1}} but cannot derive the value from a particular index of an array. For that you need to use the $ or the $slice operators.This is currently an unresolved issue: JIRA1, JIRA2)
And the $add expression becomes $add:[[],[],[],..].
$add does not take an array as input and hence you get the error stating that it does not support Array as input.
What you need to do is:

Match the documents.
Unwind the my_array field.
Group together based on the _id of each document to get the sum
of all the elements in the array skipping the first element.
Project the summed field for each grouped document.
Again group the documents based on the condition to get the sum.

Stage operators:
db.collection.aggregate([
{$match:{}}, // condition
{$unwind:"$my_array"},
{$group:{"_id":"$_id",
         "first_element":{$first:"$my_array"},
         "sum_of_all":{$sum:"$my_array"}}},
{$project:{"_id":"$_id",
           "sum_of_29":{$subtract:["$sum_of_all","$first_element"]}}},
{$group:{"_id":" ",  // whatever condition
         "my_result":{$sum:"$sum_of_29"}}}
])

