我的文件如下:
{
"_id" : "53ce85eda2579da8b40c1f0f",
"name" : "Autokino",
"tags" : [
"forMen"
],
"ratings" : [
{ "rating" : 5, "uuid" : "..."},
{ "rating" : 4, "uuid" : "..."},
{ "rating" : 4, "uuid" : "..."},
{ "rating" : 1, "uuid" : "..."},
]
}
现在我需要ratings.rating的平均值(这里应该是3.5)。我的查询如下:
activities.aggregate([
{ $match: { _id: ObjectID(req.params.id) } },
{ $unwind: '$ratings' },
{ $group: {
_id: '$_id',
rating: { $avg: '$ratings.rating'},
}},
]);
它有效,但我得到的是:
{
"_id" : "53ce85eda2579da8b40c1f0f",
"rating" : 3.5
}
这就是我需要得到的:
{
"_id" : "53ce85eda2579da8b40c1f0f",
"name" : "Autokino",
"tags" : [
"forMen"
],
"rating" : 3.5
}
(原始文件没有评级数组,但评级平均值)
我该如何解决这个问题?
答案 0 :(得分:3)
$group
和$project
之类的管道阶段是“绝对的”,因为只发出声明的字段。你需要另一个运营商。 $first
会:
activities.aggregate([
{ "$match": { "_id": ObjectID(req.params.id) } },
{ "$unwind": "$ratings" },
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"tags": { "$first": "$tags" },
"rating": { "$avg": "$ratings.rating" },
}},
]);
由于$unwind
使得数组内容中的许多文档无法规范化,因此您可以在此处使用$first
来“仅”首次出现您未以其他方式聚合的附加字段。< / p>
如果您担心许多字段以这种方式声明,MongoDB 2.6确实提供了$$ROOT
变量。我的使用和输出可能不是你真正想要的:
activities.aggregate([
{ "$match": { "_id": ObjectID(req.params.id) } },
{ "$project": {
"_id": "$$ROOT",
"ratings": 1
}},
{ "$unwind": "$ratings" },
{ "$group": {
"_id": "$_id",
"rating": { "$avg": "$ratings.rating" },
}},
]);
这给你类似的东西:
{
"_id" : {
"_id": "53ce85eda2579da8b40c1f0f",
"name" : "Autokino",
"tags" : [
"forMen"
],
"ratings" : [
{ "rating" : 5, "uuid" : "..."},
{ "rating" : 4, "uuid" : "..."},
{ "rating" : 4, "uuid" : "..."},
{ "rating" : 1, "uuid" : "..."},
]
},
"rating": 3.5
}
这是可以的,因为_id
的分组与整个文档的分组相同。因此,您始终可以添加最终$project
以返回类似状态。但这里没有通配符。
答案 1 :(得分:0)
我刚刚经历了整首歌曲和舞蹈,最后不得不重新添加我所有的领域。不太理想!
所以我发现了这个 - 更容易:我有一个评论数组字段,其评级属性为1 - 5
{
$addFields: { avg: { $avg: '$reviews.rating'}}
},