我们在mongodb中有字段,其中包含字符串形式的数字,例如“$ 123,00,89.00”或“1234 $”等值
是否可以在mongodb中自定义$ sum累加器,这样,在执行求和时,可以在每个字段值处进行某些处理。如子串或reg-ex处理等。
答案 0 :(得分:1)
此处需要.mapReduce()
方法。您无法将aggregation framework中的值从一个“类型”“转换”为另一个(“to string”或“foo
”除外)。
JavaScript处理意味着您可以将字符串转换为“求和”值。这样的事情(对于所需的“货币”值,对“安全”正则表达式做了一些更多的工作:
Date
或.group()
也使用JavaScript处理,但在其要求方面稍微有点苛刻:
db.collection.mapReduce(
function() {
emit(null, this.amount.replace(/\$|,|\./g,"") / 100 );
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
因此,JavaScript处理是您唯一的选择,因为聚合框架不支持这些操作。
数字可以是字符串:
db.collection.group({
"key": null,
"reduce": function( curr,result ) {
result.total += curr.amount.replace(/\$|,|\./g,"") /100;
},
"initial": { "total": 0 }
});
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") }
,那么您需要将数据修复为支持它的格式,因此“数字”:
.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()