【问题标题】:Convert a string to a number in MongoDB projection在 MongoDB 投影中将字符串转换为数字
【发布时间】:2014-09-22 21:15:42
【问题描述】:

我有一个文档集合,这些文档的值已知为数字,但存储为字符串。我无法控制更改字段的类型,但我想在聚合中使用该字段(例如,对其进行平均)。

似乎我应该在分组之前使用投影,并在该投影中根据需要转换字段。我似乎无法获得正确的语法 - 我尝试的所有内容要么给我 NaN,要么只是在聚合的下一步中缺少新字段。

$project: {
    value: '$value',
    valueasnumber: ????
}

鉴于上面非常简单的示例,其中所有文档中 $value 的内容都是字符串类型,但会解析为数字,我该怎么做才能使 valueasnumber 成为 double 类型的新(不存在)字段里面有 $value 的解析版本?

我已经尝试过以下示例(以及大约十几个类似的东西):

{ $add: new Number('$value').valueOf() }
new Number('$value').valueOf()

我是不是完全找错了树?任何帮助将不胜感激!

(为了 100% 清楚,以下是我想如何使用新字段)。

$group {
    score: {
        $avg: '$valueasnumber'
    }
}

【问题讨论】:

  • 从 MongoDB 2.6 开始,您就不走运了。聚合框架中没有可用的数字解析选项。如果该字段表示一个数字,它应该真正存储为一个数字;也许您可以添加另一个字段,即数字的数字形式?也可以考虑 map/reduce。
  • 感谢大家的cmets。我正在尝试这两种方法,看看哪种方法最有效。聚合框架似乎比 map/reduce 具有更好的性能,因此可能值得维护第二个字段(作为数字),以便可以按预期使用聚合。

标签: mongodb mongodb-query


【解决方案1】:

我能想到的一种方法是使用mongo shell javascript通过在现有文档或新文档中添加新的数字字段valuesasnumber(现有字符串'value'字段的数字转换)来修改文档.然后使用此数字字段进行进一步计算。

db.numbertest.find().forEach(function(doc) {
    doc.valueasnumber = new NumberInt(doc.value);
    db.numbertest.save(doc);
});

使用 valueasnumber 字段进行数值计算

db.numbertest.aggregate([{$group : 
   {_id : null, 
    "score" : {$avg : "$valueasnumber"}
   }
}]);

【讨论】:

    【解决方案2】:

    核心操作是将值从字符串转换为数字,目前aggregate pipeline operation 无法处理。
    ma​​pReduce 是一种替代方法,如下所示。

    db.c.mapReduce(function() {
        emit( this.groupId, {score: Number(this.value), count: 1} );
    }, function(key, values) {
        var score = 0, count = 0;
        for (var i = 0; i < values.length; i++) {
            score += values[i].score;
            count += values[i].count;
        }
        return {score: score, count: count};
    }, {finalize: function(key, value) {
        return {score: value.score / value.count};
    }, out: {inline: 1}});
    

    【讨论】:

      【解决方案3】:

      现在聚合中有 $toInt 转换运算符,您可以检查: https://jira.mongodb.org/browse/SERVER-11400

      【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 2011-12-11
      • 2018-11-09
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2012-06-12
      相关资源
      最近更新 更多