我有一个定义的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);
});
});
希望将来可以帮助其他人。