mongodb中的子串总和

时间:2015-07-14 00:33:13

标签: mongodb mapreduce mongodb-query aggregation-framework

我们在mongodb中有字段,其中包含字符串形式的数字,例如“$ 123,00,89.00”或“1234 $”等值

是否可以在mongodb中自定义$ sum累加器,这样,在执行求和时,可以在每个字段值处进行某些处理。如子串或reg-ex处理等。

1 个答案:

答案 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()