The basic form of what you are trying to do, and without iterating is this:
db.collection.aggregate([
{ "$group": {
"_id": {
"fr" : "$fr",
"to" : "$to",
},
"sum": { "$sum": "$weight" }
}}
])
Now that may well blow up on you so you might need to do some looping and "range" the values as in:
db.collection.aggregate([
{ "$match": {
"fr": { "$gt": 0, "$lte": 10000 },
"to": { "$gt": 0, "$lte": 10000 }
}},
{ "$group": {
"_id": {
"fr" : "$fr",
"to" : "$to",
},
"sum": { "$sum": "$weight" }
}}
])
To segment all of those documents, and then get the next segment:
db.collection.aggregate([
{ "$match": {
"fr": { "$gt": 10000, "$lte": 20000 },
"to": { "$gt": 10000, "$lte": 20000 }
}},
{ "$group": {
"_id": {
"fr" : "$fr",
"to" : "$to"
},
"sum": { "$sum": "$weight" }
}]
])
Whichever solution that works out best for you.
The general point is let $group
do the work for you and break that up into manageable chunks where the results may be too big for one fetch.
In future releases aggregate will return a cursor.