【问题标题】:Mongo convert all numeric fields that are stored as stringMongo 转换所有存储为字符串的数字字段
【发布时间】:2013-02-13 19:59:27
【问题描述】:

看起来有一段时间我一直将小数存储为字符串。现在这是一个问题,因为我需要开始使用聚合框架来执行一些计算。

有没有办法遍历我的集合中的每个文档并检查isNaN 的每个值,如果为false,则将其与parseFloat 一起存储

【问题讨论】:

    标签: javascript mongodb


    【解决方案1】:

    这样的东西应该可以在 mongo shell 中工作:

    db.yourCollection.find({}).forEach(function(doc) { 
        if(isNaN(doc.xyz)) { 
            print('found string: ' + doc._id);
            db.yourCollection.update( 
               { _id: doc._id}, 
               { $set : { "xyz" : parseFloat(doc.xyz) } }
            )
        }
    })
    

    它遍历每个文档,按照您的建议使用isNaN,然后将$sets 的值转换为当前文档的parseFloat 值。

    【讨论】:

    • 从 mongodb 2.2 开始,更新将查询作为第一个参数,因此 {_id: doc._id} 而不仅仅是 doc._id。
    • 如果你的字符串是“123”或“3456”,你应该使用typeof doc.xyz == 'string'而不是isNaN(doc.xyz)
    • @ov1d1u - 最初的问题是专门询问使用isNaN,所以我选择了它。
    【解决方案2】:

    感谢您的回复。我最初的问题并不清楚,因为我不想指定要更新为数字的字段,而是遍历每个属性并执行检查。

    我已经把这个小函数放在一起来解决这个问题:

    var cursor = db.results.find();
    while (cursor.hasNext()) {
        var doc = cursor.next();
        for (key in doc) {
            if (key.match(/^metric_.*/i) && !isNaN(doc[key])) {
                doc[key] = parseFloat(doc[key]);
                db.results.update({ _id : doc._id }, doc );
            }
        }
    }
    

    需要注意的两点:

    1. 这只会检查和转换到第一级属性。它可以轻松修改以更深入,但这就是我此时所需要的。
    2. 这个函数会炸掉你的日期值!!! isNaN 将 JavaScript 日期评估为假,因此将被视为数字。就我而言,使用parseFloat 实际上会将值设置为isNaN。同样,对于旁观者来说,这是一个非常简单的解决方案,但我只是想提供该免责声明。

    希望这可以帮助我这个职位的其他人。

    【讨论】:

      猜你喜欢
      • 2017-06-07
      • 1970-01-01
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多