Метод .mapReduce()
- это то, что вам нужно здесь. Вы не можете «отличать» значения в aggregation framework от одного «типа» к другому (за исключением «до строки» или от Date
до числового).
Обработка JavaScript означает, что вы можете преобразовать строку в значение для «суммирования». Somthing как это (с немного больше работы на «безопасном» регулярное выражение для требуемых значений «валюты»:
db.collection.mapReduce(
function() {
emit(null, this.amount.replace(/\$|,|\./g,"")/100);
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
Или с .group()
который также использует JavaScript ОБРАБОТКИ, но это немного больше restrcitive в его требованиях:
db.collection.group({
"key": null,
"reduce": function(curr,result) {
result.total += curr.amount.replace(/\$|,|\./g,"") /100;
},
"initial": { "total": 0 }
});
так JavaScript обработка единственный вариант, поскольку эти виды деятельности не поддерживаются в рамках aggregatation
номер может быть строкой:.
db.junk.aggregate([{ "$project": { "a": { "$substr": [ 1,0,1 ] } } }])
{ "_id" : ObjectId("55a458c567446a4351c804e5"), "a" : "1" }
И Date
может стать номер:
db.junk.aggregate([{ "$project": { "a": { "$subtract": [ new Date(), new Date(0) ] } } }])
{ "_id" : ObjectId("55a458c567446a4351c804e5"), "a" : NumberLong("1436835669446") }
Но нет никаких других операторов «слепок» «строка» в «Числовой» или даже Anthing, чтобы сделать Regex заменить, как показано выше.
Если вы хотите использовать .aggregate()
, то вам необходимо исправить свои данные в формат, который будет поддерживать его, таким образом, «Числовой»:
var bulk = db.collection.initializeOrderedBulkOp(),
count = 0;
db.collection.find({ "amount": /\$|,\./g }).forEach(function(doc) {
doc.amount = doc.amount.replace(/\$|,|\./g,"") /100;
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "amount": doc.amount }
});
count++;
// execute once in 1000 operations
if (count % 1000 == 0) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp();
}
});
// clean up queued operations
if (count % 1000 != 0)
bulk.execute();
Затем вы можете использовать .aggregate()
на вашей «цифровой» данные:
db.collection.aggregate([
{ "$group": { "_id": null, "total": { "$sum": "$amount" } } }
])