通过在带有Doctrine的mongodb中使用mapReduce,可以使用奇怪的对象值而不是float



我使用mongo查询来计算每个项目的总价。我的查询看起来像

$queryBuilder=新查询\生成器($this,$documentName);

$queryBuilder->field('created')->gte($startDate);
$queryBuilder->field('is_test_value')->notEqual(true);
..........
$queryBuilder->map('function() {emit(this.item, this.price)}');
$queryBuilder->reduce('function(item, valuesPrices) {
    return {sum: Array.sum(valuesPrices)}
}');

这是有效的,没问题。但我发现,在某些情况下(200个结果中大约有20个),我在字段sum中有奇怪的结果,而不是总值,我看到的是类似的结构

[objectObject]444444444444444

4-是项目的价格。

我试着把reduce块替换成这样的块:

    var sum = 0;
    for (var i = 0; i < valuesPrices.length; i++) {
        sum += parseFloat(valuesPrices[i]);
    }
    return {sum: sum}

在这种情况下,我看到NAN值。

我怀疑字段price中的某些数据插入错误(不是以浮点形式,而是以字符串、对象等形式)。我尝试从mongocli执行查询,发现所有价格值都是整数。

这一点都不"奇怪"。你"违反了规则",现在你正在为此付费。

  • MongoDB可以对同一个键多次调用reduce函数。在这种情况下,reduce功能对该键的上一次输出将成为该键下一次reduce调用的输入值之一

mapReduce的主要规则(如前所述)是必须从"reducer"返回与从"mapper"返回完全相同的结构。这是因为"reducer"实际上可以为同一个"key"运行多次。这就是mapReduce处理大型列表的方式。

你可以通过返回一个奇异值来解决这个问题,就像你在emit:中所做的那样

return Array.sum(values);

然后就不会有问题了。向中添加一个对象键会使数据不一致,因此当"reduced"结果再次反馈到"reducer"时会出现错误。

相关内容

  • 没有找到相关文章

最新更新