我有一个如此定义的猫鼬模型:
freelancerSchema = mongoose.Schema({
_id: { type: String, default: shortid.generate},
fname: String,
lname: String;
ratings: [{
rating: Number,
employer: {
type: String,
ref: 'Employer'
}
}],
...
}]
此架构表示Freelancer集合的猫鼬模型。我的问题是:在某个查询中,我需要找到所有自由职业者的所有数据,并计算每个人的平均评分。最后,我会得到一系列自由职业者,每个人都有自己的计算平均评分,最好存储在一个新的字段“avg_rating”或类似的东西中。
我已经尝试过调查mongodb Aggregate,但老实说我并不太了解。
如果我的解释不够准确,请提前致谢并对不起。
答案 0 :(得分:2)
如果我们要在这里播放code golf,那么可以缩短表达式:
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)
})
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)
})
当使用$addFields
可用的MongoDB 3.4时,所有人都使用$project
作为$reduce
的替代。使用$project
修改时的第二种形式也对MongoDB 3.2有效,第三种形式也是如此(并注明)。
答案 1 :(得分:1)
在搞乱我的代码并阅读其他一些堆栈之后,我发现了一个适合我需求的解决方案:
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);
});
});
希望将来可以帮助其他人。