用排序计算每个文档的平均值



我有一个定义的mongoose模型:

freelancerSchema = mongoose.Schema({
 _id: { type: String, default: shortid.generate},
 fname: String,
 lname: String;
 ratings: [{
       rating: Number,
       employer: {
          type: String,
          ref: 'Employer'
           }
        }],
 ...
}]

此架构代表了自由职业者收藏的猫鼬模型。我的问题是:在某个查询中,我需要找到所有具有所有数据的自由职业者,并计算每个自由职业者的平均评分。最后,我会得到一系列的自由职业者,每个自由职业者都有自己计算的平均等级,最好存储在新的字段" AVG_Rating"或类似领域中。

我已经尝试研究了MongoDB的总体,但老实说,我不太了解。

提前感谢,对不起,如果我的解释还不够精确。

如果我们要在这里打高尔夫球,则可以缩短表达式:

Freelancer.aggregate([
  { "$addFields": {
    "rating_avg": {
       "$reduce": {
        "input": "$ratings",
        "initialValue": 0,
        "in": {
          "$add": [ 
            "$$value",
            { "$divide": [ "$$this.rating", { "$size": "$ratings" } ] }
          ]
        }
      }
    }
  }},
  { "$sort": { "rating_avg": -1 } }
],function(err, results) {
  res.send(results)
})

使用$avg$map

,甚至短一点
Freelancer.aggregate([
  { "$addFields": {
    "rating_avg": {
      "$avg": {
        "$map": { 
          "input": "$ratings",
          "as": "el",
          "in": "$$el.rating"
        }
      }
    }
  }},
  { "$sort": { "rating_avg": -1 } }
],function(err, results) {
  res.send(results)
})

当然,迄今为止最短,自MongoDB 3.2以来被允许(当然使用$project修改(:

Freelancer.aggregate([
  { "$addFields": {
    "rating_avg": { "$avg": "$ratings.rating" }
  }},
  { "$sort": { "rating_avg": -1 } }
],function(err, results) {
  res.send(results)
})

使用MongoDB 3.4(这是$reduce可用的地方(时,所有这些都使用$addFields作为$project的替代方案。使用$project修改时的第二种形式也适用于MongoDB 3.2,第三个形式也是正确的(并指出(。

弄乱我的代码并阅读了其他一些堆栈后,我找到了一个满足我需求的解决方案:

   Freelancer.aggregate(
    [{
            $project: {
                fname: "$fname",
                lname: "$lname",
                rating_avg: {
                    $divide: [{
                        $reduce: {
                            input: "$ratings.rating",
                            initialValue: 0,
                            in: {
                                $sum: ["$$value", "$$this"]
                            }
                        }
                    }, {
                        $size: "$ratings"
                    }]
                }
            }
        },
        {
            $sort: {
                rating_avg: -1
            }
        }
    ],
    function (err, results) {
        res.send(results);
    });
});

希望将来可以帮助其他人。

最新更新