【问题标题】:how to populate map-reduced result如何填充地图减少的结果
【发布时间】:2012-11-20 08:05:54
【问题描述】:
TestSessionSchema.statics.getTopTesters = function(callback){
    var o = {};
    o.map = function(){
        emit(this._customer, this.points);
    };

    o.reduce = function(_customer, values){
        var result = {_customer: _customer, sum_points: 0, };
        values.forEach(function(point){
            result.sum_points += point;
        });
        return result;
    };

    o.out = { replace: 'createdCollectionNameForResults' };
    o.verbose = true;

    this.mapReduce(o,function(err, model, stats){
        model.find().sort({'value.sum_points': "desc"}).limit(5).populate("_customer").exec(function(error, results){

            log(results);

        })
    });

}

在 map-reduce 部分,我得到了 _customers 的积分。

现在我想填充 _customer 以获取客户的信息 model.find().sort({'value.sum_points': "desc"}).limit(5).populate("_customer") 不起作用

我该怎么做?

【问题讨论】:

  • 您在“结果”(或在发出)中没有使用正确的格式。 emit 的第二部分必须与 reduce 返回的“结果”格式相同。所以要么 emit(this._customer, {_customer:this._customer, sum_points:this.points} 要么使结果格式简单“result = 0”来表示点。
  • 顺便说一句,如果您将潜在问题分开会很有帮助。从您的 createdCollectionNameForResults 集合中进行简单的选择,以确保您输出的是您认为的内容。当这看起来不错时,然后尝试第二部分 - 并在它“不起作用”时发布你得到的错误

标签: node.js mongodb mongoose


【解决方案1】:

当您在 MongoDB 中执行 mapReduce 时,您必须确保您的 emit 值与您的 reduce 返回值具有相同的格式。

这意味着在您的情况下,如果 map 调用 emit(customer, points)reduce 必须仅返回 points 的值。

要更改您的具体示例,您的 map 函数是可以的,但您的 reduce 函数应该是:

reduce = function(_customer, values) {
        var result =  0;
        values.forEach(function(point){
            result += point;
        });
        return result;
    };

然后,您的 reduce 函数将汇总每个 _customer 的所有值(点),这就是您想要的。输出将是 _customer,指向字段名称为 _idvalue 的键值对,其中 value 将是该 _id (_customer) 的所有点值的总和。

要查询您将运行的结果:

db.createdCollectionNameForResults.find().sort({value:-1}).limit(5)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多