Node.js $lookup on ObjectId';对象数组中的s(猫鼬)
我有两种模式:Node.js $lookup on ObjectId';对象数组中的s(猫鼬),node.js,mongodb,express,mongoose,Node.js,Mongodb,Express,Mongoose,我有两种模式: module.exports = mongoose.model('Article', { title : String, text : String, lang : { type: String, default: 'en'}, user : { type : mongoose.Schema.Types.ObjectId, ref: 'User' }, }); var userSchema = mongoose.Schema({ email : String,
module.exports = mongoose.model('Article', {
title : String,
text : String,
lang : { type: String, default: 'en'},
user : { type : mongoose.Schema.Types.ObjectId, ref: 'User' },
});
var userSchema = mongoose.Schema({
email : String,
name : String,
rating : [{
_id: false,
articleID: {type: mongoose.Schema.Types.ObjectId, ref: 'Article'},
rate: Number
}]
});
module.exports = mongoose.model('User', userSchema);
我想计算一个用户的平均评分(其文章的所有评分的平均值)
我试过这个:
User.aggregate([
{ $unwind: "$rating" },
{
"$lookup": {
"from": "Article",
"localField": "rating.articleID",
"foreignField": "_id",
"as": "article-origin"
}
}//,
//{ $match: { "article-origin.user" : mongoose.Types.ObjectId(article.user) } }//,
//{ $group : {_id : "$rating.articleID", avgRate : { $avg : "$rating.rate" } } }
]).exec(function (err,result) {
console.log(err);
console.log(JSON.stringify(result));
});
但是如果没有成功,锁定总是返回字段项目原点null
结果:{u id:“590747e1af02570769c875dc”,“姓名:”“姓名”,“电子邮件:”“电子邮件”,“评级:{“评级”:5,“文章id:”59074a357fe6a307981e7925“}”,“文章来源:[]}
为什么不起作用?当然不需要操作符,因为组聚合操作不使用
文章
集合中的文档,它只需要一个字段,即文章ID
进行分组
有两种方法可以做到这一点。如果您的MongoDB服务器版本为3.4或更高版本,则可以在此处应用、和运算符来计算平均值,而无需重新计算
首先展平分级阵列,如果阵列较大,这可能会对性能产生一些影响
考虑运行以下管道:
User.aggregate([
{ "$match": { "_id" : mongoose.Types.ObjectId(article.user) } },
{
"$addFields": {
"avgRate": {
"$divide": [
{
"$reduce": {
"input": "$rating",
"initialValue": 0,
"in": { "$sum": ["$$value", "$$this.rate"] }
}
},
{
"$cond": [
{ "$ne": [{ "$size": "$rating" }, 0] },
{ "$size": "$rating" },
1
]
}
]
}
}
}
]).exec(function (err, result) {
console.log(err);
console.log(JSON.stringify(result));
});
如果使用MongoDB 3.2版,则首先需要评级数组:
User.aggregate([
{ "$match": { "_id" : mongoose.Types.ObjectId(article.user) } },
{ "$unwind": "$rating" },
{
"$group": {
"_id": "$_id",
"avgRate": { "$avg": "$rating.rate" }
}
}
]).exec(function (err, result) {
console.log(err);
console.log(JSON.stringify(result));
});
如果出于某种原因需要操作,则需要引用集合名称,而不是模型名称,因此应该使用正确的聚合操作
User.aggregate([
{ "$unwind": "$rating" },
{
"$lookup": {
"from": "articles", /* collection name here, not model name */
"localField": "rating.articleID",
"foreignField": "_id",
"as": "article-origin"
}
},
{ "$match": { "article-origin.user" : mongoose.Types.ObjectId(article.user) } },
{
"$group": {
"_id": "$_id",
"avgRate": { "$avg": "$rating.rate" }
}
}
]).exec(function (err, result) {
console.log(err);
console.log(JSON.stringify(result));
});